mirror of
https://github.com/bitwarden/server.git
synced 2024-11-24 12:35:25 +01:00
Start Migration from Newtonsoft.Json to System.Text.Json (#1803)
* Start switch to System.Text.Json * Work on switching to System.Text.Json * Main work on STJ refactor * Fix build errors * Run formatting * Delete unused file * Use legacy for two factor providers * Run formatter * Add TokenProviderTests * Run formatting * Fix merge issues * Switch to use JsonSerializer * Address PR feedback * Fix formatting * Ran formatter * Switch to async * Ensure Enums are serialized as strings * Fix formatting * Enqueue single items as arrays * Remove CreateAsync method on AzureQueueService
This commit is contained in:
parent
897a76ff48
commit
5268f2781e
@ -1,11 +1,12 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Admin.Controllers
|
||||
{
|
||||
@ -37,20 +38,21 @@ namespace Bit.Admin.Controllers
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<IActionResult> GetLatestDockerHubVersion(string repository)
|
||||
public async Task<IActionResult> GetLatestDockerHubVersion(string repository, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.GetAsync(
|
||||
$"https://hub.docker.com/v2/repositories/bitwarden/{repository}/tags/");
|
||||
$"https://hub.docker.com/v2/repositories/bitwarden/{repository}/tags/", cancellationToken);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var data = JObject.Parse(json);
|
||||
var results = data["results"] as JArray;
|
||||
foreach (var result in results)
|
||||
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
|
||||
var root = jsonDocument.RootElement;
|
||||
|
||||
var results = root.GetProperty("results");
|
||||
foreach (var result in results.EnumerateArray())
|
||||
{
|
||||
var name = result["name"].ToString();
|
||||
var name = result.GetProperty("name").GetString();
|
||||
if (!string.IsNullOrWhiteSpace(name) && name.Length > 0 && char.IsNumber(name[0]))
|
||||
{
|
||||
return new JsonResult(name);
|
||||
@ -63,17 +65,17 @@ namespace Bit.Admin.Controllers
|
||||
return new JsonResult("-");
|
||||
}
|
||||
|
||||
public async Task<IActionResult> GetInstalledWebVersion()
|
||||
public async Task<IActionResult> GetInstalledWebVersion(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.GetAsync(
|
||||
$"{_globalSettings.BaseServiceUri.InternalVault}/version.json");
|
||||
$"{_globalSettings.BaseServiceUri.InternalVault}/version.json", cancellationToken);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var data = JObject.Parse(json);
|
||||
return new JsonResult(data["version"].ToString());
|
||||
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
|
||||
var root = jsonDocument.RootElement;
|
||||
return new JsonResult(root.GetProperty("version").GetString());
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException) { }
|
||||
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Admin.Models;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@ -14,7 +14,6 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Admin.Controllers
|
||||
{
|
||||
@ -264,14 +263,16 @@ namespace Bit.Admin.Controllers
|
||||
{
|
||||
var license = await _organizationService.GenerateLicenseAsync(organization,
|
||||
model.InstallationId.Value, model.Version);
|
||||
return File(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(license, Formatting.Indented)),
|
||||
"text/plain", "bitwarden_organization_license.json");
|
||||
var ms = new MemoryStream();
|
||||
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
|
||||
return File(ms, "text/plain", "bitwarden_organization_license.json");
|
||||
}
|
||||
else if (user != null)
|
||||
{
|
||||
var license = await _userService.GenerateLicenseAsync(user, null, model.Version);
|
||||
return File(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(license, Formatting.Indented)),
|
||||
"text/plain", "bitwarden_premium_license.json");
|
||||
var ms = new MemoryStream();
|
||||
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
|
||||
return File(ms, "text/plain", "bitwarden_premium_license.json");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
@ -11,8 +12,6 @@ using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Admin.HostedServices
|
||||
{
|
||||
@ -70,17 +69,19 @@ namespace Bit.Admin.HostedServices
|
||||
{
|
||||
try
|
||||
{
|
||||
var token = JToken.Parse(message.DecodeMessageText());
|
||||
if (token is JArray)
|
||||
using var document = JsonDocument.Parse(message.DecodeMessageText());
|
||||
var root = document.RootElement;
|
||||
|
||||
if (root.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var mailQueueMessage in token.ToObject<List<MailQueueMessage>>())
|
||||
foreach (var mailQueueMessage in root.ToObject<List<MailQueueMessage>>())
|
||||
{
|
||||
await _mailService.SendEnqueuedMailMessageAsync(mailQueueMessage);
|
||||
}
|
||||
}
|
||||
else if (token is JObject)
|
||||
else if (root.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
var mailQueueMessage = token.ToObject<MailQueueMessage>();
|
||||
var mailQueueMessage = root.ToObject<MailQueueMessage>();
|
||||
await _mailService.SendEnqueuedMailMessageAsync(mailQueueMessage);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Admin.HostedServices
|
||||
{
|
||||
@ -65,7 +64,7 @@ namespace Bit.Admin.HostedServices
|
||||
request.RequestUri = new Uri("https://api.cloudflare.com/" +
|
||||
$"client/v4/zones/{_adminSettings.Cloudflare.ZoneId}/firewall/access_rules/rules");
|
||||
|
||||
var bodyContent = JsonConvert.SerializeObject(new
|
||||
request.Content = JsonContent.Create(new
|
||||
{
|
||||
mode = "block",
|
||||
configuration = new
|
||||
@ -75,7 +74,6 @@ namespace Bit.Admin.HostedServices
|
||||
},
|
||||
notes = $"Rate limit abuse on {DateTime.UtcNow.ToString()}."
|
||||
});
|
||||
request.Content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await _httpClient.SendAsync(request, cancellationToken);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
@ -83,8 +81,7 @@ namespace Bit.Admin.HostedServices
|
||||
return;
|
||||
}
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
var accessRuleResponse = JsonConvert.DeserializeObject<AccessRuleResponse>(responseString);
|
||||
var accessRuleResponse = await response.Content.ReadFromJsonAsync<AccessRuleResponse>(cancellationToken: cancellationToken);
|
||||
if (!accessRuleResponse.Success)
|
||||
{
|
||||
return;
|
||||
@ -118,8 +115,7 @@ namespace Bit.Admin.HostedServices
|
||||
return;
|
||||
}
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
var listResponse = JsonConvert.DeserializeObject<ListResponse>(responseString);
|
||||
var listResponse = await response.Content.ReadFromJsonAsync<ListResponse>(cancellationToken: cancellationToken);
|
||||
if (!listResponse.Success)
|
||||
{
|
||||
return;
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Azure.Documents;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Admin.Models
|
||||
{
|
||||
@ -17,40 +19,48 @@ namespace Bit.Admin.Models
|
||||
|
||||
public class LogDetailsModel : LogModel
|
||||
{
|
||||
public JObject Exception { get; set; }
|
||||
public JsonDocument Exception { get; set; }
|
||||
|
||||
public string ExceptionToString(JObject e)
|
||||
public string ExceptionToString(JsonDocument e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var val = string.Empty;
|
||||
if (e["Message"] != null && e["Message"].ToObject<string>() != null)
|
||||
var root = e.RootElement;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
if (root.TryGetProperty("Message", out var messageProp) && messageProp.GetString() != null)
|
||||
{
|
||||
val += "Message:\n";
|
||||
val += e["Message"] + "\n";
|
||||
sb.AppendLine("Message:");
|
||||
sb.AppendLine(messageProp.GetString());
|
||||
}
|
||||
|
||||
if (e["StackTrace"] != null && e["StackTrace"].ToObject<string>() != null)
|
||||
if (root.TryGetProperty("StackTrace", out var stackTraceProp) && stackTraceProp.GetString() != null)
|
||||
{
|
||||
val += "\nStack Trace:\n";
|
||||
val += e["StackTrace"];
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Stack Trace:");
|
||||
sb.Append(stackTraceProp.GetString());
|
||||
}
|
||||
else if (e["StackTraceString"] != null && e["StackTraceString"].ToObject<string>() != null)
|
||||
else if (root.TryGetProperty("StackTraceString", out var stackTraceStringProp) && stackTraceStringProp.GetString() != null)
|
||||
{
|
||||
val += "\nStack Trace String:\n";
|
||||
val += e["StackTraceString"];
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Stack Trace String:");
|
||||
sb.Append(stackTraceStringProp.GetString());
|
||||
}
|
||||
|
||||
if (e["InnerException"] != null && e["InnerException"].ToObject<JObject>() != null)
|
||||
if (root.TryGetProperty("InnerException", out var innerExceptionProp) && innerExceptionProp.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
val += "\n\n=== Inner Exception ===\n\n";
|
||||
val += ExceptionToString(e["InnerException"].ToObject<JObject>());
|
||||
sb.AppendLine();
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("=== Inner Exception ===");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(ExceptionToString(innerExceptionProp.ToObject<JsonDocument>()));
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
return val;
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Messaging.EventGrid;
|
||||
using Bit.Api.Models.Request;
|
||||
@ -21,7 +22,6 @@ using Core.Models.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Controllers
|
||||
{
|
||||
@ -802,7 +802,7 @@ namespace Bit.Api.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, $"Uncaught exception occurred while handling event grid event: {JsonConvert.SerializeObject(eventGridEvent)}");
|
||||
_logger.LogError(e, $"Uncaught exception occurred while handling event grid event: {JsonSerializer.Serialize(eventGridEvent)}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Api.Models.Request;
|
||||
using Bit.Api.Models.Request.Accounts;
|
||||
@ -17,7 +18,6 @@ using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Controllers
|
||||
{
|
||||
@ -185,7 +185,7 @@ namespace Bit.Api.Controllers
|
||||
return new OrganizationAutoEnrollStatusResponseModel(organization.Id, false);
|
||||
}
|
||||
|
||||
var data = JsonConvert.DeserializeObject<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
||||
var data = JsonSerializer.Deserialize<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
||||
return new OrganizationAutoEnrollStatusResponseModel(organization.Id, data?.AutoEnrollEnabled ?? false);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Messaging.EventGrid;
|
||||
using Bit.Api.Models.Request;
|
||||
@ -19,7 +20,6 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Controllers
|
||||
{
|
||||
@ -227,7 +227,7 @@ namespace Bit.Api.Controllers
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
var sendId = new Guid(id);
|
||||
var send = await _sendRepository.GetByIdAsync(sendId);
|
||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send?.Data);
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(send?.Data);
|
||||
|
||||
if (send == null || send.Type != SendType.File || (send.UserId.HasValue && send.UserId.Value != userId) ||
|
||||
!send.UserId.HasValue || fileData.Id != fileId || fileData.Validated)
|
||||
@ -289,7 +289,7 @@ namespace Bit.Api.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, $"Uncaught exception occurred while handling event grid event: {JsonConvert.SerializeObject(eventGridEvent)}");
|
||||
_logger.LogError(e, $"Uncaught exception occurred while handling event grid event: {JsonSerializer.Serialize(eventGridEvent)}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Public.Request
|
||||
{
|
||||
@ -17,7 +17,7 @@ namespace Bit.Api.Models.Public.Request
|
||||
public virtual Policy ToPolicy(Policy existingPolicy)
|
||||
{
|
||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||
existingPolicy.Data = Data != null ? JsonConvert.SerializeObject(Data) : null;
|
||||
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||
return existingPolicy;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models.Public.Response
|
||||
{
|
||||
@ -24,7 +25,7 @@ namespace Bit.Api.Models.Public.Response
|
||||
Enabled = policy.Enabled;
|
||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
||||
{
|
||||
Data = JsonConvert.DeserializeObject<Dictionary<string, object>>(policy.Data);
|
||||
Data = JsonSerializer.Deserialize<Dictionary<string, object>>(policy.Data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using Core.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NS = Newtonsoft.Json;
|
||||
using NSL = Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
@ -69,22 +70,20 @@ namespace Bit.Api.Models.Request
|
||||
switch (existingCipher.Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
var loginObj = JObject.FromObject(ToCipherLoginData(),
|
||||
new JsonSerializer { NullValueHandling = NullValueHandling.Ignore });
|
||||
var loginObj = NSL.JObject.FromObject(ToCipherLoginData(),
|
||||
new NS.JsonSerializer { NullValueHandling = NS.NullValueHandling.Ignore });
|
||||
// TODO: Switch to JsonNode in .NET 6 https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter?pivots=dotnet-6-0
|
||||
loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove();
|
||||
existingCipher.Data = loginObj.ToString(Formatting.None);
|
||||
existingCipher.Data = loginObj.ToString(NS.Formatting.None);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherCardData(),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherIdentityData(),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherSecureNoteData(),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
|
@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
@ -65,15 +65,13 @@ namespace Bit.Api.Models.Request
|
||||
switch (existingSend.Type)
|
||||
{
|
||||
case SendType.File:
|
||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(existingSend.Data);
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(existingSend.Data);
|
||||
fileData.Name = Name;
|
||||
fileData.Notes = Notes;
|
||||
existingSend.Data = JsonConvert.SerializeObject(fileData,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
existingSend.Data = JsonSerializer.Serialize(fileData, JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
case SendType.Text:
|
||||
existingSend.Data = JsonConvert.SerializeObject(ToSendData(),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
existingSend.Data = JsonSerializer.Serialize(ToSendData(), JsonHelpers.IgnoreWritingNull);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Request
|
||||
{
|
||||
@ -12,9 +12,9 @@ namespace Bit.Api.Models.Request
|
||||
|
||||
public User ToUser(User existingUser)
|
||||
{
|
||||
existingUser.EquivalentDomains = EquivalentDomains != null ? JsonConvert.SerializeObject(EquivalentDomains) : null;
|
||||
existingUser.EquivalentDomains = EquivalentDomains != null ? JsonSerializer.Serialize(EquivalentDomains) : null;
|
||||
existingUser.ExcludedGlobalEquivalentDomains = ExcludedGlobalEquivalentDomains != null ?
|
||||
JsonConvert.SerializeObject(ExcludedGlobalEquivalentDomains) : null;
|
||||
JsonSerializer.Serialize(ExcludedGlobalEquivalentDomains) : null;
|
||||
return existingUser;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Data;
|
||||
@ -18,7 +19,7 @@ namespace Bit.Api.Models.Response
|
||||
Url = $"{globalSettings.Attachment.BaseUrl}/{cipher.Id}/{id}";
|
||||
FileName = data.FileName;
|
||||
Key = data.Key;
|
||||
Size = data.SizeString;
|
||||
Size = data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||
}
|
||||
|
||||
@ -26,7 +27,8 @@ namespace Bit.Api.Models.Response
|
||||
public string Url { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string Size { get; set; }
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public long Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
|
||||
public static IEnumerable<AttachmentResponseModel> FromCipher(Cipher cipher, IGlobalSettings globalSettings)
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
using Core.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
@ -28,25 +28,25 @@ namespace Bit.Api.Models.Response
|
||||
switch (cipher.Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
var loginData = JsonConvert.DeserializeObject<CipherLoginData>(cipher.Data);
|
||||
var loginData = JsonSerializer.Deserialize<CipherLoginData>(cipher.Data);
|
||||
cipherData = loginData;
|
||||
Data = loginData;
|
||||
Login = new CipherLoginModel(loginData);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
var secureNoteData = JsonConvert.DeserializeObject<CipherSecureNoteData>(cipher.Data);
|
||||
var secureNoteData = JsonSerializer.Deserialize<CipherSecureNoteData>(cipher.Data);
|
||||
Data = secureNoteData;
|
||||
cipherData = secureNoteData;
|
||||
SecureNote = new CipherSecureNoteModel(secureNoteData);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
var cardData = JsonConvert.DeserializeObject<CipherCardData>(cipher.Data);
|
||||
var cardData = JsonSerializer.Deserialize<CipherCardData>(cipher.Data);
|
||||
Data = cardData;
|
||||
cipherData = cardData;
|
||||
Card = new CipherCardModel(cardData);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
var identityData = JsonConvert.DeserializeObject<CipherIdentityData>(cipher.Data);
|
||||
var identityData = JsonSerializer.Deserialize<CipherIdentityData>(cipher.Data);
|
||||
Data = identityData;
|
||||
cipherData = identityData;
|
||||
Identity = new CipherIdentityModel(identityData);
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
@ -19,10 +19,10 @@ namespace Bit.Api.Models.Response
|
||||
}
|
||||
|
||||
EquivalentDomains = user.EquivalentDomains != null ?
|
||||
JsonConvert.DeserializeObject<List<List<string>>>(user.EquivalentDomains) : null;
|
||||
JsonSerializer.Deserialize<List<List<string>>>(user.EquivalentDomains) : null;
|
||||
|
||||
var excludedGlobalEquivalentDomains = user.ExcludedGlobalEquivalentDomains != null ?
|
||||
JsonConvert.DeserializeObject<List<GlobalEquivalentDomainsType>>(user.ExcludedGlobalEquivalentDomains) :
|
||||
JsonSerializer.Deserialize<List<GlobalEquivalentDomainsType>>(user.ExcludedGlobalEquivalentDomains) :
|
||||
new List<GlobalEquivalentDomainsType>();
|
||||
var globalDomains = new List<GlobalDomains>();
|
||||
var domainsToInclude = excluded ? Core.Utilities.StaticStore.GlobalDomains :
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
@ -23,7 +23,7 @@ namespace Bit.Api.Models.Response
|
||||
Enabled = policy.Enabled;
|
||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
||||
{
|
||||
Data = JsonConvert.DeserializeObject<Dictionary<string, object>>(policy.Data);
|
||||
Data = JsonSerializer.Deserialize<Dictionary<string, object>>(policy.Data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
@ -26,12 +26,12 @@ namespace Bit.Api.Models.Response
|
||||
switch (send.Type)
|
||||
{
|
||||
case SendType.File:
|
||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||
sendData = fileData;
|
||||
File = new SendFileModel(fileData);
|
||||
break;
|
||||
case SendType.Text:
|
||||
var textData = JsonConvert.DeserializeObject<SendTextData>(send.Data);
|
||||
var textData = JsonSerializer.Deserialize<SendTextData>(send.Data);
|
||||
sendData = textData;
|
||||
Text = new SendTextModel(textData);
|
||||
break;
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Models.Response
|
||||
{
|
||||
@ -36,12 +36,12 @@ namespace Bit.Api.Models.Response
|
||||
switch (send.Type)
|
||||
{
|
||||
case SendType.File:
|
||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||
sendData = fileData;
|
||||
File = new SendFileModel(fileData);
|
||||
break;
|
||||
case SendType.Text:
|
||||
var textData = JsonConvert.DeserializeObject<SendTextData>(send.Data);
|
||||
var textData = JsonSerializer.Deserialize<SendTextData>(send.Data);
|
||||
sendData = textData;
|
||||
Text = new SendTextModel(textData);
|
||||
break;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Api.Models
|
||||
@ -11,7 +12,7 @@ namespace Bit.Api.Models
|
||||
{
|
||||
Id = data.Id;
|
||||
FileName = data.FileName;
|
||||
Size = data.SizeString;
|
||||
Size = data.Size;
|
||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||
}
|
||||
|
||||
@ -19,7 +20,8 @@ namespace Bit.Api.Models
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string FileName { get; set; }
|
||||
public string Size { get; set; }
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public long Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Messaging.EventGrid;
|
||||
using Azure.Messaging.EventGrid.SystemEvents;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Utilities
|
||||
{
|
||||
@ -27,7 +27,7 @@ namespace Bit.Api.Utilities
|
||||
var s = await reader.ReadToEndAsync();
|
||||
if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
obj = JsonConvert.DeserializeObject<T>(s);
|
||||
obj = JsonSerializer.Deserialize<T>(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Api.Models.Request;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -7,7 +8,6 @@ using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Api.Utilities
|
||||
{
|
||||
@ -78,13 +78,6 @@ namespace Bit.Api.Utilities
|
||||
{
|
||||
if (ContentDispositionHeaderValue.TryParse(firstSection.ContentDisposition, out _))
|
||||
{
|
||||
// Request model json, then data
|
||||
string requestModelJson = null;
|
||||
using (var sr = new StreamReader(firstSection.Body))
|
||||
{
|
||||
requestModelJson = await sr.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var secondSection = await reader.ReadNextSectionAsync();
|
||||
if (secondSection != null)
|
||||
{
|
||||
@ -94,7 +87,7 @@ namespace Bit.Api.Utilities
|
||||
var fileName = HeaderUtilities.RemoveQuotes(secondContent.FileName).ToString();
|
||||
using (secondSection.Body)
|
||||
{
|
||||
var model = JsonConvert.DeserializeObject<SendRequestModel>(requestModelJson);
|
||||
var model = await JsonSerializer.DeserializeAsync<SendRequestModel>(firstSection.Body);
|
||||
await callback(secondSection.Body, fileName, model);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Billing.Controllers
|
||||
{
|
||||
@ -53,7 +53,7 @@ namespace Bit.Billing.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(body), Formatting.Indented);
|
||||
var json = JsonSerializer.Serialize(JsonSerializer.Deserialize<JsonDocument>(body), JsonHelpers.Indented);
|
||||
_logger.LogInformation(Constants.BypassFiltersEventId, "Apple IAP Notification:\n\n{0}", json);
|
||||
return new OkResult();
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
@ -13,7 +14,6 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Billing.Controllers
|
||||
{
|
||||
@ -62,23 +62,18 @@ namespace Bit.Billing.Controllers
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
string body = null;
|
||||
using (var reader = new StreamReader(HttpContext.Request.Body, Encoding.UTF8))
|
||||
{
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(body))
|
||||
using var body = await JsonSerializer.DeserializeAsync<JsonDocument>(HttpContext.Request.Body);
|
||||
var root = body.RootElement;
|
||||
if (root.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dynamic data = JsonConvert.DeserializeObject(body);
|
||||
string ticketId = data.ticket_id;
|
||||
string ticketContactEmail = data.ticket_contact_email;
|
||||
string ticketTags = data.ticket_tags;
|
||||
var ticketId = root.GetProperty("ticket_id").GetString();
|
||||
var ticketContactEmail = root.GetProperty("ticket_contact_email").GetString();
|
||||
var ticketTags = root.GetProperty("ticket_tags").GetString();
|
||||
if (string.IsNullOrWhiteSpace(ticketId) || string.IsNullOrWhiteSpace(ticketContactEmail))
|
||||
{
|
||||
return new BadRequestResult();
|
||||
@ -120,9 +115,11 @@ namespace Bit.Billing.Controllers
|
||||
updateBody.Add("tags", tagsToUpdate);
|
||||
}
|
||||
var updateRequest = new HttpRequestMessage(HttpMethod.Put,
|
||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId));
|
||||
updateRequest.Content = new StringContent(JsonConvert.SerializeObject(updateBody),
|
||||
Encoding.UTF8, "application/json");
|
||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId))
|
||||
{
|
||||
Content = JsonContent.Create(updateBody),
|
||||
};
|
||||
|
||||
await CallFreshdeskApiAsync(updateRequest);
|
||||
|
||||
|
||||
@ -132,9 +129,10 @@ namespace Bit.Billing.Controllers
|
||||
{ "private", true }
|
||||
};
|
||||
var noteRequest = new HttpRequestMessage(HttpMethod.Post,
|
||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}/notes", ticketId));
|
||||
noteRequest.Content = new StringContent(JsonConvert.SerializeObject(noteBody),
|
||||
Encoding.UTF8, "application/json");
|
||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}/notes", ticketId))
|
||||
{
|
||||
Content = JsonContent.Create(noteBody),
|
||||
};
|
||||
await CallFreshdeskApiAsync(noteRequest);
|
||||
}
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
using System;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Bit.Billing.Models
|
||||
{
|
||||
public class AppleReceiptNotification
|
||||
{
|
||||
[JsonProperty("notification_type")]
|
||||
public string NotificationType { get; set; }
|
||||
[JsonProperty("environment")]
|
||||
public string Environment { get; set; }
|
||||
[JsonProperty("auto_renew_status")]
|
||||
public string AutoRenewStatus { get; set; }
|
||||
[JsonProperty("auto_renew_product_id")]
|
||||
public string AutoRenewProductId { get; set; }
|
||||
[JsonProperty("auto_renew_status_change_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime? AutoRenewStatusChangeDate { get; set; }
|
||||
[JsonProperty("latest_receipt")]
|
||||
public string LatestReceipt { get; set; }
|
||||
[JsonProperty("latest_receipt_info")]
|
||||
public AppleReceiptNotificationInfo LatestReceiptInfo { get; set; }
|
||||
[JsonProperty("latest_expired_receipt")]
|
||||
public string LatestExpiredReceipt { get; set; }
|
||||
[JsonProperty("latest_expired_receipt_info")]
|
||||
public AppleReceiptNotificationInfo LatestExpiredReceiptInfo { get; set; }
|
||||
|
||||
public string GetOriginalTransactionId()
|
||||
{
|
||||
if (LatestReceiptInfo != null)
|
||||
{
|
||||
return LatestReceiptInfo.OriginalTransactionId;
|
||||
}
|
||||
return LatestExpiredReceiptInfo?.OriginalTransactionId;
|
||||
}
|
||||
|
||||
public string GetTransactionId()
|
||||
{
|
||||
if (LatestReceiptInfo != null)
|
||||
{
|
||||
return LatestReceiptInfo.TransactionId;
|
||||
}
|
||||
return LatestExpiredReceiptInfo?.TransactionId;
|
||||
}
|
||||
|
||||
public DateTime? GetExpiresDate()
|
||||
{
|
||||
if (LatestReceiptInfo != null)
|
||||
{
|
||||
return LatestReceiptInfo.ExpiresDate;
|
||||
}
|
||||
return LatestExpiredReceiptInfo?.ExpiresDate;
|
||||
}
|
||||
|
||||
public string GetReceiptData()
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(LatestReceipt) ? LatestExpiredReceipt : LatestReceipt;
|
||||
}
|
||||
|
||||
public class AppleReceiptNotificationInfo
|
||||
{
|
||||
[JsonProperty("bid")]
|
||||
public string Bid { get; set; }
|
||||
public string ProductId { get; set; }
|
||||
[JsonProperty("original_purchase_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime? OriginalPurchaseDate { get; set; }
|
||||
[JsonProperty("expires_date")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime? ExpiresDate { get; set; }
|
||||
[JsonProperty("purchase_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime? PurchaseDate { get; set; }
|
||||
[JsonProperty("subscription_group_identifier")]
|
||||
public string SubscriptionGroupIdentifier { get; set; }
|
||||
[JsonProperty("unique_identifier")]
|
||||
public string UniqueIdentifier { get; set; }
|
||||
[JsonProperty("original_transaction_id")]
|
||||
public string OriginalTransactionId { get; set; }
|
||||
[JsonProperty("transaction_id")]
|
||||
public string TransactionId { get; set; }
|
||||
[JsonProperty("quantity")]
|
||||
public string Quantity { get; set; }
|
||||
[JsonProperty("web_order_line_item_id")]
|
||||
public string WebOrderLineItemId { get; set; }
|
||||
[JsonProperty("item_id")]
|
||||
public string ItemId { get; set; }
|
||||
}
|
||||
|
||||
public class MsEpochConverter : DateTimeConverterBase
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteRawValue(CoreHelpers.ToEpocMilliseconds((DateTime)value).ToString());
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
return CoreHelpers.FromEpocMilliseconds(long.Parse(reader.Value.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Entities
|
||||
{
|
||||
@ -42,7 +42,7 @@ namespace Bit.Core.Entities
|
||||
|
||||
try
|
||||
{
|
||||
_attachmentData = JsonConvert.DeserializeObject<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
|
||||
_attachmentData = JsonSerializer.Deserialize<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
|
||||
foreach (var kvp in _attachmentData)
|
||||
{
|
||||
kvp.Value.AttachmentId = kvp.Key;
|
||||
@ -65,7 +65,7 @@ namespace Bit.Core.Entities
|
||||
}
|
||||
|
||||
_attachmentData = data;
|
||||
Attachments = JsonConvert.SerializeObject(_attachmentData);
|
||||
Attachments = JsonSerializer.Serialize(_attachmentData);
|
||||
}
|
||||
|
||||
public void AddAttachment(string id, CipherAttachment.MetaData data)
|
||||
|
@ -2,10 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Entities
|
||||
{
|
||||
@ -142,13 +142,13 @@ namespace Bit.Core.Entities
|
||||
if (_twoFactorProviders == null)
|
||||
{
|
||||
_twoFactorProviders =
|
||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
JsonSerializer.Deserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
TwoFactorProviders);
|
||||
}
|
||||
|
||||
return _twoFactorProviders;
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -163,10 +163,7 @@ namespace Bit.Core.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
TwoFactorProviders = JsonConvert.SerializeObject(providers, new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new EnumKeyResolver<byte>()
|
||||
});
|
||||
TwoFactorProviders = JsonSerializer.Serialize(providers);
|
||||
_twoFactorProviders = providers;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Entities
|
||||
{
|
||||
@ -108,13 +108,13 @@ namespace Bit.Core.Entities
|
||||
if (_twoFactorProviders == null)
|
||||
{
|
||||
_twoFactorProviders =
|
||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
TwoFactorProviders);
|
||||
}
|
||||
|
||||
return _twoFactorProviders;
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -132,10 +132,7 @@ namespace Bit.Core.Entities
|
||||
|
||||
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
|
||||
{
|
||||
TwoFactorProviders = JsonConvert.SerializeObject(providers, new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new EnumKeyResolver<byte>()
|
||||
});
|
||||
TwoFactorProviders = JsonHelpers.LegacySerialize(providers);
|
||||
_twoFactorProviders = providers;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -10,7 +11,6 @@ using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using U2F.Core.Exceptions;
|
||||
using U2F.Core.Models;
|
||||
using U2F.Core.Utils;
|
||||
@ -107,8 +107,8 @@ namespace Bit.Core.Identity
|
||||
});
|
||||
}
|
||||
|
||||
var oldToken = JsonConvert.SerializeObject(oldChallenges);
|
||||
var token = JsonConvert.SerializeObject(new
|
||||
var oldToken = JsonSerializer.Serialize(oldChallenges);
|
||||
var token = JsonSerializer.Serialize(new
|
||||
{
|
||||
appId = appId,
|
||||
challenge = challengeBytes.ByteArrayToBase64String(),
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -12,7 +13,6 @@ using Fido2NetLib;
|
||||
using Fido2NetLib.Objects;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Identity
|
||||
{
|
||||
@ -98,7 +98,7 @@ namespace Bit.Core.Identity
|
||||
return false;
|
||||
}
|
||||
|
||||
var clientResponse = JsonConvert.DeserializeObject<AuthenticatorAssertionRawResponse>(token);
|
||||
var clientResponse = JsonSerializer.Deserialize<AuthenticatorAssertionRawResponse>(token);
|
||||
|
||||
var jsonOptions = provider.MetaData["login"].ToString();
|
||||
var options = AssertionOptions.FromJson(jsonOptions);
|
||||
|
@ -15,7 +15,7 @@
|
||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||
<td class="content-block last" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0; -webkit-text-size-adjust: none; text-align: center;" valign="top" align="center">
|
||||
If you do not wish to join this organization, you can safely ignore this email.
|
||||
{{#if OrganizationCanSponsor}}
|
||||
{{#jsonIf OrganizationCanSponsor}}
|
||||
<p style="margin-top:10px">
|
||||
<b
|
||||
style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||
@ -24,7 +24,7 @@
|
||||
Members of {{OrganizationName}} receive a complimentary Families subscription. Learn more at the
|
||||
following link: https://bitwarden.com/help/article/families-for-enterprise/
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/jsonIf}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -6,7 +6,7 @@ You have been invited to join the {{OrganizationName}} organization. To accept t
|
||||
This link expires on {{ExpirationDate}}.
|
||||
|
||||
If you do not wish to join this organization, you can safely ignore this email.
|
||||
{{#if OrganizationCanSponsor}}
|
||||
{{#jsonIf OrganizationCanSponsor}}
|
||||
Did you know? Members of {{OrganizationName}} receive a complimentary Families subscription. Learn more here: https://bitwarden.com/help/article/families-for-enterprise/
|
||||
{{/if}}
|
||||
{{/jsonIf}}
|
||||
{{/BasicTextLayout}}
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Models.Api.Request.Accounts
|
||||
{
|
||||
@ -43,7 +43,7 @@ namespace Bit.Core.Models.Api.Request.Accounts
|
||||
|
||||
if (ReferenceData != null)
|
||||
{
|
||||
user.ReferenceData = JsonConvert.SerializeObject(ReferenceData);
|
||||
user.ReferenceData = JsonSerializer.Serialize(ReferenceData);
|
||||
}
|
||||
|
||||
if (Key != null)
|
||||
|
@ -1,27 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Bit.Billing.Models
|
||||
{
|
||||
public class AppleReceiptStatus
|
||||
{
|
||||
[JsonProperty("status")]
|
||||
[JsonPropertyName("status")]
|
||||
public int? Status { get; set; }
|
||||
[JsonProperty("environment")]
|
||||
[JsonPropertyName("environment")]
|
||||
public string Environment { get; set; }
|
||||
[JsonProperty("latest_receipt")]
|
||||
[JsonPropertyName("latest_receipt")]
|
||||
public string LatestReceipt { get; set; }
|
||||
[JsonProperty("receipt")]
|
||||
[JsonPropertyName("receipt")]
|
||||
public AppleReceipt Receipt { get; set; }
|
||||
[JsonProperty("latest_receipt_info")]
|
||||
[JsonPropertyName("latest_receipt_info")]
|
||||
public List<AppleTransaction> LatestReceiptInfo { get; set; }
|
||||
[JsonProperty("pending_renewal_info")]
|
||||
[JsonPropertyName("pending_renewal_info")]
|
||||
public List<AppleRenewalInfo> PendingRenewalInfo { get; set; }
|
||||
|
||||
public string GetOriginalTransactionId()
|
||||
@ -81,72 +82,59 @@ namespace Bit.Billing.Models
|
||||
|
||||
public class AppleReceipt
|
||||
{
|
||||
[JsonProperty("receipt_type")]
|
||||
[JsonPropertyName("receipt_type")]
|
||||
public string ReceiptType { get; set; }
|
||||
[JsonProperty("bundle_id")]
|
||||
[JsonPropertyName("bundle_id")]
|
||||
public string BundleId { get; set; }
|
||||
[JsonProperty("receipt_creation_date_ms")]
|
||||
[JsonPropertyName("receipt_creation_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime ReceiptCreationDate { get; set; }
|
||||
[JsonProperty("in_app")]
|
||||
[JsonPropertyName("in_app")]
|
||||
public List<AppleTransaction> InApp { get; set; }
|
||||
}
|
||||
|
||||
public class AppleRenewalInfo
|
||||
{
|
||||
[JsonProperty("expiration_intent")]
|
||||
[JsonPropertyName("expiration_intent")]
|
||||
public string ExpirationIntent { get; set; }
|
||||
[JsonProperty("auto_renew_product_id")]
|
||||
[JsonPropertyName("auto_renew_product_id")]
|
||||
public string AutoRenewProductId { get; set; }
|
||||
[JsonProperty("original_transaction_id")]
|
||||
[JsonPropertyName("original_transaction_id")]
|
||||
public string OriginalTransactionId { get; set; }
|
||||
[JsonProperty("is_in_billing_retry_period")]
|
||||
[JsonPropertyName("is_in_billing_retry_period")]
|
||||
public string IsInBillingRetryPeriod { get; set; }
|
||||
[JsonProperty("product_id")]
|
||||
[JsonPropertyName("product_id")]
|
||||
public string ProductId { get; set; }
|
||||
[JsonProperty("auto_renew_status")]
|
||||
[JsonPropertyName("auto_renew_status")]
|
||||
public string AutoRenewStatus { get; set; }
|
||||
}
|
||||
|
||||
public class AppleTransaction
|
||||
{
|
||||
[JsonProperty("quantity")]
|
||||
[JsonPropertyName("quantity")]
|
||||
public string Quantity { get; set; }
|
||||
[JsonProperty("product_id")]
|
||||
[JsonPropertyName("product_id")]
|
||||
public string ProductId { get; set; }
|
||||
[JsonProperty("transaction_id")]
|
||||
[JsonPropertyName("transaction_id")]
|
||||
public string TransactionId { get; set; }
|
||||
[JsonProperty("original_transaction_id")]
|
||||
[JsonPropertyName("original_transaction_id")]
|
||||
public string OriginalTransactionId { get; set; }
|
||||
[JsonProperty("purchase_date_ms")]
|
||||
[JsonPropertyName("purchase_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime PurchaseDate { get; set; }
|
||||
[JsonProperty("original_purchase_date_ms")]
|
||||
[JsonPropertyName("original_purchase_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime OriginalPurchaseDate { get; set; }
|
||||
[JsonProperty("expires_date_ms")]
|
||||
[JsonPropertyName("expires_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime ExpiresDate { get; set; }
|
||||
[JsonProperty("cancellation_date_ms")]
|
||||
[JsonPropertyName("cancellation_date_ms")]
|
||||
[JsonConverter(typeof(MsEpochConverter))]
|
||||
public DateTime? CancellationDate { get; set; }
|
||||
[JsonProperty("web_order_line_item_id")]
|
||||
[JsonPropertyName("web_order_line_item_id")]
|
||||
public string WebOrderLineItemId { get; set; }
|
||||
[JsonProperty("cancellation_reason")]
|
||||
[JsonPropertyName("cancellation_reason")]
|
||||
public string CancellationReason { get; set; }
|
||||
}
|
||||
|
||||
public class MsEpochConverter : DateTimeConverterBase
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteRawValue(CoreHelpers.ToEpocMilliseconds((DateTime)value).ToString());
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
return CoreHelpers.FromEpocMilliseconds(long.Parse(reader.Value.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Models.Business
|
||||
{
|
||||
|
@ -1,13 +1,10 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Business
|
||||
{
|
||||
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||
public class ReferenceEvent
|
||||
{
|
||||
public ReferenceEvent() { }
|
||||
@ -23,10 +20,10 @@ namespace Bit.Core.Models.Business
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public ReferenceEventType Type { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public ReferenceEventSource Source { get; set; }
|
||||
|
||||
public Guid Id { get; set; }
|
||||
@ -52,7 +49,7 @@ namespace Bit.Core.Models.Business
|
||||
|
||||
public short? Storage { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public SendType? SendType { get; set; }
|
||||
|
||||
public int? MaxAccessCount { get; set; }
|
||||
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Business
|
||||
{
|
||||
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
||||
public class ReferenceEventData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Layout { get; set; }
|
||||
|
||||
public string Flow { get; set; }
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@ using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Services;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Models.Business
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
@ -15,21 +15,14 @@ namespace Bit.Core.Models.Data
|
||||
{
|
||||
private long _size;
|
||||
|
||||
[JsonIgnore]
|
||||
// We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public long Size
|
||||
{
|
||||
get { return _size; }
|
||||
set { _size = value; }
|
||||
}
|
||||
|
||||
// We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers
|
||||
[JsonProperty("Size")]
|
||||
public string SizeString
|
||||
{
|
||||
get { return _size.ToString(); }
|
||||
set { _size = Convert.ToInt64(value); }
|
||||
}
|
||||
|
||||
public string FileName { get; set; }
|
||||
public string Key { get; set; }
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
@ -37,13 +38,13 @@ namespace Bit.Core.Models.Data
|
||||
if (_twoFactorProviders == null)
|
||||
{
|
||||
_twoFactorProviders =
|
||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||
TwoFactorProviders);
|
||||
}
|
||||
|
||||
return _twoFactorProviders;
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
catch (Newtonsoft.Json.JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
@ -25,7 +25,6 @@ namespace Bit.Core.Models.Data
|
||||
public bool ManageResetPassword { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
|
||||
{
|
||||
(AccessEventLogs, "accesseventlogs"),
|
||||
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class SendFileData : SendData
|
||||
{
|
||||
private long _size;
|
||||
|
||||
public SendFileData() { }
|
||||
|
||||
public SendFileData(string name, string notes, string fileName)
|
||||
@ -15,20 +13,9 @@ namespace Bit.Core.Models.Data
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public long Size
|
||||
{
|
||||
get { return _size; }
|
||||
set { _size = value; }
|
||||
}
|
||||
|
||||
// We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers
|
||||
[JsonProperty("Size")]
|
||||
public string SizeString
|
||||
{
|
||||
get { return _size.ToString(); }
|
||||
set { _size = Convert.ToInt64(value); }
|
||||
}
|
||||
[JsonNumberHandling(JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString)]
|
||||
public long Size { get; set; }
|
||||
|
||||
public string Id { get; set; }
|
||||
public string FileName { get; set; }
|
||||
|
@ -9,6 +9,6 @@ namespace Bit.Core.Models.Mail
|
||||
IEnumerable<string> BccEmails { get; set; }
|
||||
string Category { get; set; }
|
||||
string TemplateName { get; set; }
|
||||
dynamic Model { get; set; }
|
||||
object Model { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Models.Mail
|
||||
{
|
||||
@ -11,12 +11,13 @@ namespace Bit.Core.Models.Mail
|
||||
public IEnumerable<string> BccEmails { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string TemplateName { get; set; }
|
||||
[JsonConverter(typeof(ExpandoObjectJsonConverter))]
|
||||
public dynamic Model { get; set; }
|
||||
|
||||
[JsonConverter(typeof(HandlebarsObjectJsonConverter))]
|
||||
public object Model { get; set; }
|
||||
|
||||
public MailQueueMessage() { }
|
||||
|
||||
public MailQueueMessage(MailMessage message, string templateName, dynamic model)
|
||||
public MailQueueMessage(MailMessage message, string templateName, object model)
|
||||
{
|
||||
Subject = message.Subject;
|
||||
ToEmails = message.ToEmails;
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json.Serialization;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Fido2NetLib.Objects;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using PeterO.Cbor;
|
||||
using U2F.Core.Utils;
|
||||
|
||||
@ -102,7 +102,7 @@ namespace Bit.Core.Models
|
||||
catch
|
||||
{
|
||||
// Handle newtonsoft parsing
|
||||
Descriptor = JsonConvert.DeserializeObject<PublicKeyCredentialDescriptor>(o.Descriptor.ToString());
|
||||
Descriptor = JsonHelpers.LegacyDeserialize<PublicKeyCredentialDescriptor>(o.Descriptor.ToString());
|
||||
}
|
||||
PublicKey = o.PublicKey;
|
||||
UserHandle = o.UserHandle;
|
||||
|
@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Billing.Models;
|
||||
using Bit.Core.Repositories;
|
||||
@ -9,8 +11,6 @@ using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -97,14 +97,16 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var url = string.Format("https://{0}.itunes.apple.com/verifyReceipt", prod ? "buy" : "sandbox");
|
||||
var json = new JObject(new JProperty("receipt-data", receiptData),
|
||||
new JProperty("password", _globalSettings.AppleIap.Password)).ToString();
|
||||
|
||||
var response = await _httpClient.PostAsync(url, new StringContent(json));
|
||||
var response = await _httpClient.PostAsJsonAsync(url, new AppleVerifyReceiptRequestModel
|
||||
{
|
||||
ReceiptData = receiptData,
|
||||
Password = _globalSettings.AppleIap.Password
|
||||
});
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseJson = await response.Content.ReadAsStringAsync();
|
||||
var receiptStatus = JsonConvert.DeserializeObject<AppleReceiptStatus>(responseJson);
|
||||
var receiptStatus = await response.Content.ReadFromJsonAsync<AppleReceiptStatus>();
|
||||
if (receiptStatus.Status == 21007)
|
||||
{
|
||||
return await GetReceiptStatusAsync(receiptData, false, attempt + 1, receiptStatus);
|
||||
@ -124,4 +126,12 @@ namespace Bit.Core.Services
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class AppleVerifyReceiptRequestModel
|
||||
{
|
||||
[JsonPropertyName("receipt-data")]
|
||||
public string ReceiptData { get; set; }
|
||||
[JsonPropertyName("password")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -13,7 +13,9 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public AzureQueueEventWriteService(GlobalSettings globalSettings) : base(
|
||||
new QueueClient(globalSettings.Events.ConnectionString, "event"),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })
|
||||
JsonHelpers.IgnoreWritingNull)
|
||||
{ }
|
||||
|
||||
public Task CreateAsync(IEvent e) => CreateManyAsync(new[] { e });
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Models.Mail;
|
||||
using Bit.Core.Settings;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -13,11 +13,11 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public AzureQueueMailService(GlobalSettings globalSettings) : base(
|
||||
new QueueClient(globalSettings.Mail.ConnectionString, "mail"),
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })
|
||||
JsonHelpers.IgnoreWritingNull)
|
||||
{ }
|
||||
|
||||
public Task EnqueueAsync(IMailQueueMessage message, Func<IMailQueueMessage, Task> fallback) =>
|
||||
CreateAsync(message);
|
||||
CreateManyAsync(new[] { message });
|
||||
|
||||
public Task EnqueueManyAsync(IEnumerable<IMailQueueMessage> messages, Func<IMailQueueMessage, Task> fallback) =>
|
||||
CreateManyAsync(messages);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Context;
|
||||
@ -7,8 +8,8 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -18,11 +19,6 @@ namespace Bit.Core.Services
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
public AzureQueuePushNotificationService(
|
||||
GlobalSettings globalSettings,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
@ -170,8 +166,8 @@ namespace Bit.Core.Services
|
||||
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
|
||||
{
|
||||
var contextId = GetContextIdentifier(excludeCurrentContext);
|
||||
var message = JsonConvert.SerializeObject(new PushNotificationData<T>(type, payload, contextId),
|
||||
_jsonSettings);
|
||||
var message = JsonSerializer.Serialize(new PushNotificationData<T>(type, payload, contextId),
|
||||
JsonHelpers.IgnoreWritingNull);
|
||||
await _queueClient.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Settings;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -14,10 +15,6 @@ namespace Bit.Core.Services
|
||||
|
||||
private readonly QueueClient _queueClient;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
};
|
||||
|
||||
public AzureQueueReferenceEventService(
|
||||
GlobalSettings globalSettings)
|
||||
@ -40,7 +37,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
try
|
||||
{
|
||||
var message = JsonConvert.SerializeObject(referenceEvent, _jsonSerializerSettings);
|
||||
var message = JsonSerializer.Serialize(referenceEvent, JsonHelpers.IgnoreWritingNullAndCamelCase);
|
||||
// Messages need to be base64 encoded
|
||||
var encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(message));
|
||||
await _queueClient.SendMessageAsync(encodedMessage);
|
||||
|
@ -1,29 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public abstract class AzureQueueService<T>
|
||||
{
|
||||
protected QueueClient _queueClient;
|
||||
protected JsonSerializerSettings _jsonSettings;
|
||||
protected JsonSerializerOptions _jsonOptions;
|
||||
|
||||
protected AzureQueueService(QueueClient queueClient, JsonSerializerSettings jsonSettings)
|
||||
protected AzureQueueService(QueueClient queueClient, JsonSerializerOptions jsonOptions)
|
||||
{
|
||||
_queueClient = queueClient;
|
||||
_jsonSettings = jsonSettings;
|
||||
}
|
||||
|
||||
public async Task CreateAsync(T message)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(message, _jsonSettings);
|
||||
var base64 = CoreHelpers.Base64EncodeString(json);
|
||||
await _queueClient.SendMessageAsync(base64);
|
||||
_jsonOptions = jsonOptions;
|
||||
}
|
||||
|
||||
public async Task CreateManyAsync(IEnumerable<T> messages)
|
||||
@ -33,19 +26,13 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
if (!messages.Skip(1).Any())
|
||||
{
|
||||
await CreateAsync(messages.First());
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var json in SerializeMany(messages, _jsonSettings))
|
||||
foreach (var json in SerializeMany(messages, _jsonOptions))
|
||||
{
|
||||
await _queueClient.SendMessageAsync(json);
|
||||
}
|
||||
}
|
||||
|
||||
protected IEnumerable<string> SerializeMany(IEnumerable<T> messages, JsonSerializerSettings jsonSettings)
|
||||
protected IEnumerable<string> SerializeMany(IEnumerable<T> messages, JsonSerializerOptions jsonOptions)
|
||||
{
|
||||
// Calculate Base-64 encoded text with padding
|
||||
int getBase64Size(int byteCount) => ((4 * byteCount / 3) + 3) & ~3;
|
||||
@ -69,7 +56,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var serializedMessages = messages.Select(message =>
|
||||
JsonConvert.SerializeObject(message, jsonSettings));
|
||||
JsonSerializer.Serialize(message, jsonOptions));
|
||||
|
||||
foreach (var message in serializedMessages)
|
||||
{
|
||||
|
@ -3,23 +3,23 @@ using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public abstract class BaseIdentityClientService
|
||||
public abstract class BaseIdentityClientService : IDisposable
|
||||
{
|
||||
private readonly string _identityScope;
|
||||
private readonly string _identityClientId;
|
||||
private readonly string _identityClientSecret;
|
||||
private readonly ILogger<BaseIdentityClientService> _logger;
|
||||
|
||||
private dynamic _decodedToken;
|
||||
private JsonDocument _decodedToken;
|
||||
private DateTime? _nextAuthAttempt = null;
|
||||
|
||||
public BaseIdentityClientService(
|
||||
@ -127,9 +127,9 @@ namespace Bit.Core.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
dynamic tokenResponse = JsonConvert.DeserializeObject(responseContent);
|
||||
AccessToken = (string)tokenResponse.access_token;
|
||||
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
|
||||
|
||||
AccessToken = jsonDocument.RootElement.GetProperty("access_token").GetString();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -145,8 +145,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (requestObject != null)
|
||||
{
|
||||
var stringContent = JsonConvert.SerializeObject(requestObject);
|
||||
Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
|
||||
Content = JsonContent.Create(requestObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,17 +153,16 @@ namespace Bit.Core.Services
|
||||
protected bool TokenNeedsRefresh(int minutes = 5)
|
||||
{
|
||||
var decoded = DecodeToken();
|
||||
var exp = decoded?["exp"];
|
||||
if (exp == null)
|
||||
if (!decoded.RootElement.TryGetProperty("exp", out var expProp))
|
||||
{
|
||||
throw new InvalidOperationException("No exp in token.");
|
||||
}
|
||||
|
||||
var expiration = CoreHelpers.FromEpocSeconds(exp.Value<long>());
|
||||
var expiration = CoreHelpers.FromEpocSeconds(expProp.GetInt64());
|
||||
return DateTime.UtcNow.AddMinutes(-1 * minutes) > expiration;
|
||||
}
|
||||
|
||||
protected JObject DecodeToken()
|
||||
protected JsonDocument DecodeToken()
|
||||
{
|
||||
if (_decodedToken != null)
|
||||
{
|
||||
@ -188,8 +186,13 @@ namespace Bit.Core.Services
|
||||
throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts");
|
||||
}
|
||||
|
||||
_decodedToken = JObject.Parse(Encoding.UTF8.GetString(decodedBytes, 0, decodedBytes.Length));
|
||||
_decodedToken = JsonDocument.Parse(decodedBytes);
|
||||
return _decodedToken;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_decodedToken.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -12,7 +13,6 @@ using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Core.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -208,7 +208,7 @@ namespace Bit.Core.Services
|
||||
UserId = cipher.UserId,
|
||||
OrganizationId = cipher.OrganizationId,
|
||||
AttachmentId = attachmentId,
|
||||
AttachmentData = JsonConvert.SerializeObject(data)
|
||||
AttachmentData = JsonSerializer.Serialize(data)
|
||||
});
|
||||
cipher.AddAttachment(attachmentId, data);
|
||||
await _pushService.PushSyncCipherUpdateAsync(cipher, null);
|
||||
@ -241,7 +241,7 @@ namespace Bit.Core.Services
|
||||
UserId = cipher.UserId,
|
||||
OrganizationId = cipher.OrganizationId,
|
||||
AttachmentId = attachmentId,
|
||||
AttachmentData = JsonConvert.SerializeObject(data)
|
||||
AttachmentData = JsonSerializer.Serialize(data)
|
||||
};
|
||||
|
||||
await _cipherRepository.UpdateAttachmentAsync(attachment);
|
||||
@ -312,7 +312,7 @@ namespace Bit.Core.Services
|
||||
UserId = cipher.UserId,
|
||||
OrganizationId = cipher.OrganizationId,
|
||||
AttachmentId = attachmentId,
|
||||
AttachmentData = JsonConvert.SerializeObject(attachments[attachmentId])
|
||||
AttachmentData = JsonSerializer.Serialize(attachments[attachmentId])
|
||||
};
|
||||
|
||||
await _cipherRepository.UpdateAttachmentAsync(updatedAttachment);
|
||||
@ -347,7 +347,7 @@ namespace Bit.Core.Services
|
||||
UserId = cipher.UserId,
|
||||
OrganizationId = cipher.OrganizationId,
|
||||
AttachmentId = attachmentData.AttachmentId,
|
||||
AttachmentData = JsonConvert.SerializeObject(attachmentData)
|
||||
AttachmentData = JsonSerializer.Serialize(attachmentData)
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
@ -8,7 +10,6 @@ using Bit.Core.Models.Business.Tokenables;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Tokens;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -77,9 +78,9 @@ namespace Bit.Core.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
var responseContent = await responseMessage.Content.ReadAsStringAsync();
|
||||
dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent);
|
||||
return (bool)jsonResponse.success;
|
||||
using var jsonDocument = await responseMessage.Content.ReadFromJsonAsync<JsonDocument>();
|
||||
var root = jsonDocument.RootElement;
|
||||
return root.GetProperty("success").GetBoolean();
|
||||
}
|
||||
|
||||
public bool RequireCaptchaValidation(ICurrentContext currentContext) =>
|
||||
|
@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Entities.Provider;
|
||||
@ -565,6 +566,35 @@ namespace Bit.Core.Services
|
||||
var clickTrackingText = (clickTrackingOff ? "clicktracking=off" : string.Empty);
|
||||
writer.WriteSafeString($"<a href=\"{href}\" target=\"_blank\" {clickTrackingText}>{text}</a>");
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("jsonIf", (output, options, context, arguments) =>
|
||||
{
|
||||
// Special case for JsonElement
|
||||
if (arguments[0] is JsonElement jsonElement
|
||||
&& (jsonElement.ValueKind == JsonValueKind.True || jsonElement.ValueKind == JsonValueKind.False))
|
||||
{
|
||||
if (jsonElement.GetBoolean())
|
||||
{
|
||||
options.Template(output, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Inverse(output, context);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback to normal
|
||||
if (HandlebarsUtils.IsTruthy(arguments[0]))
|
||||
{
|
||||
options.Template(output, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Inverse(output, context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SendEmergencyAccessInviteEmailAsync(EmergencyAccess emergencyAccess, string name, string token)
|
||||
|
@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
@ -13,7 +14,6 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -246,7 +246,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var data = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
return JsonConvert.DeserializeObject<UserLicense>(data);
|
||||
return JsonSerializer.Deserialize<UserLicense>(data);
|
||||
}
|
||||
|
||||
private OrganizationLicense ReadOrganizationLicense(Organization organization)
|
||||
@ -258,7 +258,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var data = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
return JsonConvert.DeserializeObject<OrganizationLicense>(data);
|
||||
return JsonSerializer.Deserialize<OrganizationLicense>(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
@ -11,7 +12,6 @@ using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Azure.NotificationHubs;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -229,7 +229,7 @@ namespace Bit.Core.Services
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "type", ((byte)type).ToString() },
|
||||
{ "payload", JsonConvert.SerializeObject(payload) }
|
||||
{ "payload", JsonSerializer.Serialize(payload) }
|
||||
}, tag);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ using Bit.Core.Models;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -18,11 +17,6 @@ namespace Bit.Core.Services
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
public NotificationsApiPushNotificationService(
|
||||
GlobalSettings globalSettings,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
|
@ -15,7 +15,6 @@ using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Stripe;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
@ -727,8 +726,8 @@ namespace Bit.Core.Services
|
||||
|
||||
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
||||
Directory.CreateDirectory(dir);
|
||||
System.IO.File.WriteAllText($"{dir}/{organization.Id}.json",
|
||||
JsonConvert.SerializeObject(license, Formatting.Indented));
|
||||
using var fs = System.IO.File.OpenWrite(Path.Combine(dir, $"{organization.Id}.json"));
|
||||
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -900,8 +899,8 @@ namespace Bit.Core.Services
|
||||
|
||||
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
||||
Directory.CreateDirectory(dir);
|
||||
System.IO.File.WriteAllText($"{dir}/{organization.Id}.json",
|
||||
JsonConvert.SerializeObject(license, Formatting.Indented));
|
||||
using var fs = System.IO.File.OpenWrite(Path.Combine(dir, $"{organization.Id}.json"));
|
||||
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||
|
||||
organization.Name = license.Name;
|
||||
organization.BusinessName = license.BusinessName;
|
||||
@ -1146,10 +1145,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (invite.Permissions != null)
|
||||
{
|
||||
orgUser.Permissions = System.Text.Json.JsonSerializer.Serialize(invite.Permissions, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
orgUser.Permissions = JsonSerializer.Serialize(invite.Permissions, JsonHelpers.CamelCase);
|
||||
}
|
||||
|
||||
if (!orgUser.AccessAll && invite.Collections.Any())
|
||||
@ -1765,7 +1761,7 @@ namespace Bit.Core.Services
|
||||
// Block the user from withdrawal if auto enrollment is enabled
|
||||
if (resetPasswordKey == null && resetPasswordPolicy.Data != null)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
||||
var data = JsonSerializer.Deserialize<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
||||
|
||||
if (data?.AutoEnrollEnabled ?? false)
|
||||
{
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -76,15 +75,13 @@ namespace Bit.Core.Services
|
||||
request.tag = string.Concat(request.tag, "-Cat_", message.Category);
|
||||
}
|
||||
|
||||
var reqJson = JsonConvert.SerializeObject(request);
|
||||
var responseMessage = await httpClient.PostAsync(
|
||||
var responseMessage = await httpClient.PostAsJsonAsync(
|
||||
$"https://{_globalSettings.Mail.PostalDomain}/api/v1/send/message",
|
||||
new StringContent(reqJson, Encoding.UTF8, "application/json"));
|
||||
request);
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await responseMessage.Content.ReadAsStringAsync();
|
||||
var response = JsonConvert.DeserializeObject<PostalResponse>(json);
|
||||
var response = await responseMessage.Content.ReadFromJsonAsync<PostalResponse>();
|
||||
if (response.status != "success")
|
||||
{
|
||||
_logger.LogError("Postal send status was not successful: {0}, {1}",
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
@ -12,7 +13,6 @@ using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -104,8 +104,8 @@ namespace Bit.Core.Services
|
||||
data.Id = fileId;
|
||||
data.Size = fileLength;
|
||||
data.Validated = false;
|
||||
send.Data = JsonConvert.SerializeObject(data,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
send.Data = JsonSerializer.Serialize(data,
|
||||
JsonHelpers.IgnoreWritingNull);
|
||||
await SaveSendAsync(send);
|
||||
return await _sendFileStorageService.GetSendFileUploadUrlAsync(send, fileId);
|
||||
}
|
||||
@ -129,7 +129,7 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("Not a File Type Send.");
|
||||
}
|
||||
|
||||
var data = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
||||
var data = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||
|
||||
if (data.Validated)
|
||||
{
|
||||
@ -146,7 +146,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> ValidateSendFile(Send send)
|
||||
{
|
||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
||||
var fileData = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||
|
||||
var (valid, realSize) = await _sendFileStorageService.ValidateFileAsync(send, fileData.Id, fileData.Size, _fileSizeLeeway);
|
||||
|
||||
@ -163,8 +163,8 @@ namespace Bit.Core.Services
|
||||
fileData.Size = realSize.Value;
|
||||
}
|
||||
fileData.Validated = true;
|
||||
send.Data = JsonConvert.SerializeObject(fileData,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
send.Data = JsonSerializer.Serialize(fileData,
|
||||
JsonHelpers.IgnoreWritingNull);
|
||||
await SaveSendAsync(send);
|
||||
|
||||
return valid;
|
||||
@ -175,7 +175,7 @@ namespace Bit.Core.Services
|
||||
await _sendRepository.DeleteAsync(send);
|
||||
if (send.Type == Enums.SendType.File)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
||||
var data = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||
await _sendFileStorageService.DeleteFileAsync(send, data.Id);
|
||||
}
|
||||
await _pushService.PushSyncSendDeleteAsync(send);
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
@ -19,7 +20,6 @@ using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using File = System.IO.File;
|
||||
using U2fLib = U2F.Core.Crypto.U2F;
|
||||
|
||||
@ -983,7 +983,8 @@ namespace Bit.Core.Services
|
||||
|
||||
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
||||
Directory.CreateDirectory(dir);
|
||||
File.WriteAllText($"{dir}/{user.Id}.json", JsonConvert.SerializeObject(license, Formatting.Indented));
|
||||
using var fs = File.OpenWrite(Path.Combine(dir, $"{user.Id}.json"));
|
||||
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1068,7 +1069,8 @@ namespace Bit.Core.Services
|
||||
|
||||
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
||||
Directory.CreateDirectory(dir);
|
||||
File.WriteAllText($"{dir}/{user.Id}.json", JsonConvert.SerializeObject(license, Formatting.Indented));
|
||||
using var fs = File.OpenWrite(Path.Combine(dir, $"{user.Id}.json"));
|
||||
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||
|
||||
user.Premium = license.Premium;
|
||||
user.RevisionDate = DateTime.UtcNow;
|
||||
|
@ -23,7 +23,6 @@ using Bit.Core.Settings;
|
||||
using IdentityModel;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using MimeKit;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
@ -332,12 +331,12 @@ namespace Bit.Core.Utilities
|
||||
|
||||
/// <summary>
|
||||
/// Creates a clone of the given object through serializing to json and deserializing.
|
||||
/// This method is subject to the limitations of Newstonsoft. For example, properties with
|
||||
/// This method is subject to the limitations of System.Text.Json. For example, properties with
|
||||
/// inaccessible setters will not be set.
|
||||
/// </summary>
|
||||
public static T CloneObject<T>(T obj)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
|
||||
return JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(obj));
|
||||
}
|
||||
|
||||
public static bool SettingHasValue(string setting)
|
||||
|
@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
@ -41,10 +40,8 @@ namespace Bit.Core.Utilities
|
||||
$"Slow down! Too many requests. Try again in {rule.Period}." : _options.QuotaExceededMessage;
|
||||
httpContext.Response.Headers["Retry-After"] = retryAfter;
|
||||
httpContext.Response.StatusCode = _options.HttpStatusCode;
|
||||
|
||||
httpContext.Response.ContentType = "application/json";
|
||||
var errorModel = new ErrorResponseModel { Message = message };
|
||||
return httpContext.Response.WriteAsync(JsonConvert.SerializeObject(errorModel));
|
||||
return httpContext.Response.WriteAsJsonAsync(errorModel, cancellationToken: httpContext.RequestAborted);
|
||||
}
|
||||
|
||||
public override void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity,
|
||||
|
@ -15,9 +15,9 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Utilities.Duo
|
||||
{
|
||||
@ -175,7 +175,7 @@ namespace Bit.Core.Utilities.Duo
|
||||
var res = ApiCall(method, path, parameters, timeout, out var statusCode);
|
||||
try
|
||||
{
|
||||
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
|
||||
var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(res);
|
||||
if (dict["stat"] as string == "OK")
|
||||
{
|
||||
return dict["response"] as T;
|
||||
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
public class EnumKeyResolver<T> : DefaultContractResolver where T : struct
|
||||
{
|
||||
protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
|
||||
{
|
||||
var contract = base.CreateDictionaryContract(objectType);
|
||||
var keyType = contract.DictionaryKeyType;
|
||||
|
||||
if (keyType.BaseType == typeof(Enum))
|
||||
{
|
||||
contract.DictionaryKeyResolver = propName => ((T)Enum.Parse(keyType, propName)).ToString();
|
||||
}
|
||||
|
||||
return contract;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Dynamic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
public class ExpandoObjectJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanWrite => false;
|
||||
public override bool CanConvert(Type objectType) => true;
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
return serializer.Deserialize<ExpandoObject>(reader);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
20
src/Core/Utilities/HandlebarsObjectJsonConverter.cs
Normal file
20
src/Core/Utilities/HandlebarsObjectJsonConverter.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
public class HandlebarsObjectJsonConverter : JsonConverter<object>
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => true;
|
||||
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options);
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize(writer, value, options);
|
||||
}
|
||||
}
|
||||
}
|
106
src/Core/Utilities/JsonHelpers.cs
Normal file
106
src/Core/Utilities/JsonHelpers.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using NS = Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
public static class JsonHelpers
|
||||
{
|
||||
public static JsonSerializerOptions Default { get; }
|
||||
public static JsonSerializerOptions Indented { get; }
|
||||
public static JsonSerializerOptions IgnoreWritingNull { get; }
|
||||
public static JsonSerializerOptions CamelCase { get; }
|
||||
public static JsonSerializerOptions IgnoreWritingNullAndCamelCase { get; }
|
||||
|
||||
static JsonHelpers()
|
||||
{
|
||||
Default = new JsonSerializerOptions();
|
||||
|
||||
Indented = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
IgnoreWritingNull = new JsonSerializerOptions
|
||||
{
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
};
|
||||
|
||||
CamelCase = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
};
|
||||
|
||||
IgnoreWritingNullAndCamelCase = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
};
|
||||
}
|
||||
|
||||
// NOTE: This is built into .NET 6, it SHOULD be removed when we upgrade
|
||||
public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options = null)
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(element.GetRawText(), options ?? Default);
|
||||
}
|
||||
|
||||
public static T DeserializeOrNew<T>(string json, JsonSerializerOptions options = null)
|
||||
where T : new()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize<T>(json, options);
|
||||
}
|
||||
|
||||
#region Legacy Newtonsoft.Json usage
|
||||
private const string LegacyMessage = "Usage of Newtonsoft.Json should be kept to a minimum and will further be removed when we move to .NET 6";
|
||||
|
||||
[Obsolete(LegacyMessage)]
|
||||
public static NS.JsonSerializerSettings LegacyDefault { get; } = new NS.JsonSerializerSettings();
|
||||
|
||||
[Obsolete(LegacyMessage)]
|
||||
public static string LegacySerialize(object value, NS.JsonSerializerSettings settings = null)
|
||||
{
|
||||
return NS.JsonConvert.SerializeObject(value, settings ?? LegacyDefault);
|
||||
}
|
||||
|
||||
[Obsolete(LegacyMessage)]
|
||||
public static T LegacyDeserialize<T>(string value, NS.JsonSerializerSettings settings = null)
|
||||
{
|
||||
return NS.JsonConvert.DeserializeObject<T>(value, settings ?? LegacyDefault);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class MsEpochConverter : JsonConverter<DateTime?>
|
||||
{
|
||||
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!long.TryParse(reader.GetString(), out var milliseconds))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CoreHelpers.FromEpocMilliseconds(milliseconds);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
|
||||
{
|
||||
if (!value.HasValue)
|
||||
{
|
||||
writer.WriteNullValue();
|
||||
}
|
||||
|
||||
writer.WriteStringValue(CoreHelpers.ToEpocMilliseconds(value.Value).ToString());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
@ -11,8 +12,6 @@ using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.EventsProcessor
|
||||
{
|
||||
@ -109,30 +108,27 @@ namespace Bit.EventsProcessor
|
||||
_logger.LogInformation("Processing message.");
|
||||
var events = new List<IEvent>();
|
||||
|
||||
var token = JToken.Parse(message);
|
||||
if (token is JArray)
|
||||
using var jsonDocument = JsonDocument.Parse(message);
|
||||
var root = jsonDocument.RootElement;
|
||||
if (root.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
var indexedEntities = token.ToObject<List<EventMessage>>()
|
||||
var indexedEntities = root.ToObject<List<EventMessage>>()
|
||||
.SelectMany(e => EventTableEntity.IndexEvent(e));
|
||||
events.AddRange(indexedEntities);
|
||||
}
|
||||
else if (token is JObject)
|
||||
else if (root.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
var eventMessage = token.ToObject<EventMessage>();
|
||||
var eventMessage = root.ToObject<EventMessage>();
|
||||
events.AddRange(EventTableEntity.IndexEvent(eventMessage));
|
||||
}
|
||||
|
||||
await _eventWriteService.CreateManyAsync(events);
|
||||
_logger.LogInformation("Processed message.");
|
||||
}
|
||||
catch (JsonReaderException)
|
||||
catch (JsonException)
|
||||
{
|
||||
_logger.LogError("JsonReaderException: Unable to parse message.");
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
{
|
||||
_logger.LogError("JsonSerializationException: Unable to serialize token.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,14 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Core.Models.Data;
|
||||
using Dapper;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories
|
||||
{
|
||||
@ -106,8 +105,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
public async Task CreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
cipher.SetNewId();
|
||||
var objWithCollections = JsonConvert.DeserializeObject<CipherWithCollections>(
|
||||
JsonConvert.SerializeObject(cipher));
|
||||
var objWithCollections = JsonSerializer.Deserialize<CipherWithCollections>(
|
||||
JsonSerializer.Serialize(cipher));
|
||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -133,8 +132,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
public async Task CreateAsync(CipherDetails cipher, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
cipher.SetNewId();
|
||||
var objWithCollections = JsonConvert.DeserializeObject<CipherDetailsWithCollections>(
|
||||
JsonConvert.SerializeObject(cipher));
|
||||
var objWithCollections = JsonSerializer.Deserialize<CipherDetailsWithCollections>(
|
||||
JsonSerializer.Serialize(cipher));
|
||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -170,8 +169,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
|
||||
public async Task<bool> ReplaceAsync(Cipher obj, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
var objWithCollections = JsonConvert.DeserializeObject<CipherWithCollections>(
|
||||
JsonConvert.SerializeObject(obj));
|
||||
var objWithCollections = JsonSerializer.Deserialize<CipherWithCollections>(
|
||||
JsonSerializer.Serialize(obj));
|
||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -3,14 +3,13 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Dapper;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories
|
||||
{
|
||||
@ -112,7 +111,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
public async Task CreateAsync(Collection obj, IEnumerable<SelectionReadOnly> groups)
|
||||
{
|
||||
obj.SetNewId();
|
||||
var objWithGroups = JsonConvert.DeserializeObject<CollectionWithGroups>(JsonConvert.SerializeObject(obj));
|
||||
var objWithGroups = JsonSerializer.Deserialize<CollectionWithGroups>(JsonSerializer.Serialize(obj));
|
||||
objWithGroups.Groups = groups.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
@ -126,7 +125,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
|
||||
public async Task ReplaceAsync(Collection obj, IEnumerable<SelectionReadOnly> groups)
|
||||
{
|
||||
var objWithGroups = JsonConvert.DeserializeObject<CollectionWithGroups>(JsonConvert.SerializeObject(obj));
|
||||
var objWithGroups = JsonSerializer.Deserialize<CollectionWithGroups>(JsonSerializer.Serialize(obj));
|
||||
objWithGroups.Groups = groups.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
@ -10,7 +11,6 @@ using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Dapper;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories
|
||||
{
|
||||
@ -95,7 +95,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
public async Task CreateAsync(Group obj, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
obj.SetNewId();
|
||||
var objWithCollections = JsonConvert.DeserializeObject<GroupWithCollections>(JsonConvert.SerializeObject(obj));
|
||||
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj));
|
||||
objWithCollections.Collections = collections.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
@ -109,7 +109,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
|
||||
public async Task ReplaceAsync(Group obj, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
var objWithCollections = JsonConvert.DeserializeObject<GroupWithCollections>(JsonConvert.SerializeObject(obj));
|
||||
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj));
|
||||
objWithCollections.Collections = collections.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -11,7 +12,6 @@ using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Dapper;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories
|
||||
{
|
||||
@ -244,8 +244,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
public async Task<Guid> CreateAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
obj.SetNewId();
|
||||
var objWithCollections = JsonConvert.DeserializeObject<OrganizationUserWithCollections>(
|
||||
JsonConvert.SerializeObject(obj));
|
||||
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
|
||||
JsonSerializer.Serialize(obj));
|
||||
objWithCollections.Collections = collections.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
@ -261,8 +261,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
||||
|
||||
public async Task ReplaceAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
||||
{
|
||||
var objWithCollections = JsonConvert.DeserializeObject<OrganizationUserWithCollections>(
|
||||
JsonConvert.SerializeObject(obj));
|
||||
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
|
||||
JsonSerializer.Serialize(obj));
|
||||
objWithCollections.Collections = collections.ToArrayTVP();
|
||||
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System.Threading;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Notifications
|
||||
{
|
||||
@ -12,7 +12,7 @@ namespace Bit.Notifications
|
||||
public static async Task SendNotificationToHubAsync(string notificationJson,
|
||||
IHubContext<NotificationsHub> hubContext, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var notification = JsonConvert.DeserializeObject<PushNotificationData<object>>(notificationJson);
|
||||
var notification = JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson);
|
||||
switch (notification.Type)
|
||||
{
|
||||
case PushType.SyncCipherUpdate:
|
||||
@ -20,7 +20,7 @@ namespace Bit.Notifications
|
||||
case PushType.SyncCipherDelete:
|
||||
case PushType.SyncLoginDelete:
|
||||
var cipherNotification =
|
||||
JsonConvert.DeserializeObject<PushNotificationData<SyncCipherPushNotification>>(
|
||||
JsonSerializer.Deserialize<PushNotificationData<SyncCipherPushNotification>>(
|
||||
notificationJson);
|
||||
if (cipherNotification.Payload.UserId.HasValue)
|
||||
{
|
||||
@ -38,7 +38,7 @@ namespace Bit.Notifications
|
||||
case PushType.SyncFolderCreate:
|
||||
case PushType.SyncFolderDelete:
|
||||
var folderNotification =
|
||||
JsonConvert.DeserializeObject<PushNotificationData<SyncFolderPushNotification>>(
|
||||
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
|
||||
notificationJson);
|
||||
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
|
||||
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
|
||||
@ -49,7 +49,7 @@ namespace Bit.Notifications
|
||||
case PushType.SyncSettings:
|
||||
case PushType.LogOut:
|
||||
var userNotification =
|
||||
JsonConvert.DeserializeObject<PushNotificationData<UserPushNotification>>(
|
||||
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
|
||||
notificationJson);
|
||||
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
|
||||
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
|
||||
@ -58,7 +58,7 @@ namespace Bit.Notifications
|
||||
case PushType.SyncSendUpdate:
|
||||
case PushType.SyncSendDelete:
|
||||
var sendNotification =
|
||||
JsonConvert.DeserializeObject<PushNotificationData<SyncSendPushNotification>>(
|
||||
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
|
||||
notificationJson);
|
||||
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
|
||||
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using AutoFixture.Xunit2;
|
||||
using Bit.Api.Controllers;
|
||||
@ -14,7 +15,6 @@ using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Bit.Api.Test.Controllers
|
||||
|
||||
send.Id = default;
|
||||
send.Type = SendType.Text;
|
||||
send.Data = JsonConvert.SerializeObject(new Dictionary<string, string>());
|
||||
send.Data = JsonSerializer.Serialize(new Dictionary<string, string>());
|
||||
send.HideEmail = true;
|
||||
|
||||
_sendService.AccessAsync(id, null).Returns((send, false, false));
|
||||
@ -81,4 +81,3 @@ namespace Bit.Api.Test.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Utilities;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Bit.Test.Common.Helpers
|
||||
{
|
||||
@ -29,10 +29,9 @@ namespace Bit.Test.Common.Helpers
|
||||
|
||||
if (actualPropInfo == null)
|
||||
{
|
||||
var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
|
||||
throw new Exception(string.Concat($"Expected actual object to contain a property named {expectedPropInfo.Name}, but it does not\n",
|
||||
$"Expected:\n{JsonConvert.SerializeObject(expected, settings)}\n",
|
||||
$"Actual:\n{JsonConvert.SerializeObject(actual, new JsonSerializerSettings { Formatting = Formatting.Indented })}"));
|
||||
$"Expected:\n{JsonSerializer.Serialize(expected, JsonHelpers.Indented)}\n",
|
||||
$"Actual:\n{JsonSerializer.Serialize(actual, JsonHelpers.Indented)}"));
|
||||
}
|
||||
|
||||
if (expectedPropInfo.PropertyType == typeof(string) || expectedPropInfo.PropertyType.IsValueType)
|
||||
@ -54,5 +53,16 @@ namespace Bit.Test.Common.Helpers
|
||||
Assert.Equal(expected, actual);
|
||||
return true;
|
||||
};
|
||||
|
||||
public static JsonElement AssertJsonProperty(JsonElement element, string propertyName, JsonValueKind jsonValueKind)
|
||||
{
|
||||
if (!element.TryGetProperty(propertyName, out var subElement))
|
||||
{
|
||||
throw new XunitException($"Could not find property by name '{propertyName}'");
|
||||
}
|
||||
|
||||
Assert.Equal(jsonValueKind, subElement.ValueKind);
|
||||
return subElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace Bit.Core.Test.AutoFixture.CipherAttachmentMetaData
|
||||
protected virtual IPostprocessComposer<CipherAttachment.MetaData> ComposerAction(IFixture fixture,
|
||||
ICustomizationComposer<CipherAttachment.MetaData> composer)
|
||||
{
|
||||
return composer.With(d => d.Size, fixture.Create<long>()).Without(d => d.SizeString);
|
||||
return composer.With(d => d.Size, fixture.Create<long>());
|
||||
}
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
|
41
test/Core.Test/Identity/AuthenticationTokenProviderTests.cs
Normal file
41
test/Core.Test/Identity/AuthenticationTokenProviderTests.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Identity
|
||||
{
|
||||
public class AuthenticationTokenProviderTests : BaseTokenProviderTests<AuthenticatorTokenProvider>
|
||||
{
|
||||
public override TwoFactorProviderType TwoFactorProviderType => TwoFactorProviderType.Authenticator;
|
||||
|
||||
public static IEnumerable<object[]> CanGenerateTwoFactorTokenAsyncData
|
||||
=> SetupCanGenerateData(
|
||||
(
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Key"] = "stuff",
|
||||
},
|
||||
true
|
||||
),
|
||||
(
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Key"] = ""
|
||||
},
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
[Theory, BitMemberAutoData(nameof(CanGenerateTwoFactorTokenAsyncData))]
|
||||
public override async Task RunCanGenerateTwoFactorTokenAsync(Dictionary<string, object> metaData, bool expectedResponse,
|
||||
User user, SutProvider<AuthenticatorTokenProvider> sutProvider)
|
||||
{
|
||||
await base.RunCanGenerateTwoFactorTokenAsync(metaData, expectedResponse, user, sutProvider);
|
||||
}
|
||||
}
|
||||
}
|
97
test/Core.Test/Identity/BaseTokenProviderTests.cs
Normal file
97
test/Core.Test/Identity/BaseTokenProviderTests.cs
Normal file
@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Identity
|
||||
{
|
||||
[SutProviderCustomize]
|
||||
public abstract class BaseTokenProviderTests<T>
|
||||
where T : IUserTwoFactorTokenProvider<User>
|
||||
{
|
||||
public abstract TwoFactorProviderType TwoFactorProviderType { get; }
|
||||
|
||||
#region Helpers
|
||||
protected static IEnumerable<object[]> SetupCanGenerateData(params (Dictionary<string, object> MetaData, bool ExpectedResponse)[] data)
|
||||
{
|
||||
return data.Select(d =>
|
||||
new object[]
|
||||
{
|
||||
d.MetaData,
|
||||
d.ExpectedResponse,
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual IUserService AdditionalSetup(SutProvider<T> sutProvider, User user)
|
||||
{
|
||||
var userService = Substitute.For<IUserService>();
|
||||
|
||||
sutProvider.GetDependency<IServiceProvider>()
|
||||
.GetService(typeof(IUserService))
|
||||
.Returns(userService);
|
||||
|
||||
SetupUserService(userService, user);
|
||||
|
||||
return userService;
|
||||
}
|
||||
|
||||
protected virtual void SetupUserService(IUserService userService, User user)
|
||||
{
|
||||
userService
|
||||
.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType, user)
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
protected static UserManager<User> SubstituteUserManager()
|
||||
{
|
||||
return new UserManager<User>(Substitute.For<IUserStore<User>>(),
|
||||
Substitute.For<IOptions<IdentityOptions>>(),
|
||||
Substitute.For<IPasswordHasher<User>>(),
|
||||
Enumerable.Empty<IUserValidator<User>>(),
|
||||
Enumerable.Empty<IPasswordValidator<User>>(),
|
||||
Substitute.For<ILookupNormalizer>(),
|
||||
Substitute.For<IdentityErrorDescriber>(),
|
||||
Substitute.For<IServiceProvider>(),
|
||||
Substitute.For<ILogger<UserManager<User>>>());
|
||||
}
|
||||
|
||||
protected void MockDatabase(User user, Dictionary<string, object> metaData)
|
||||
{
|
||||
var providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
[TwoFactorProviderType] = new TwoFactorProvider
|
||||
{
|
||||
Enabled = true,
|
||||
MetaData = metaData,
|
||||
},
|
||||
};
|
||||
|
||||
user.TwoFactorProviders = JsonHelpers.LegacySerialize(providers);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public virtual async Task RunCanGenerateTwoFactorTokenAsync(Dictionary<string, object> metaData, bool expectedResponse,
|
||||
User user, SutProvider<T> sutProvider)
|
||||
{
|
||||
var userManager = SubstituteUserManager();
|
||||
MockDatabase(user, metaData);
|
||||
|
||||
AdditionalSetup(sutProvider, user);
|
||||
|
||||
var response = await sutProvider.Sut.CanGenerateTwoFactorTokenAsync(userManager, user);
|
||||
Assert.Equal(expectedResponse, response);
|
||||
}
|
||||
}
|
||||
}
|
48
test/Core.Test/Identity/EmailTokenProviderTests.cs
Normal file
48
test/Core.Test/Identity/EmailTokenProviderTests.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Identity
|
||||
{
|
||||
public class EmailTokenProviderTests : BaseTokenProviderTests<EmailTokenProvider>
|
||||
{
|
||||
public override TwoFactorProviderType TwoFactorProviderType => TwoFactorProviderType.Email;
|
||||
|
||||
public static IEnumerable<object[]> CanGenerateTwoFactorTokenAsyncData
|
||||
=> SetupCanGenerateData(
|
||||
(
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Email"] = "test@email.com",
|
||||
},
|
||||
true
|
||||
),
|
||||
(
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["NotEmail"] = "value",
|
||||
},
|
||||
false
|
||||
),
|
||||
(
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Email"] = "",
|
||||
},
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
[Theory, BitMemberAutoData(nameof(CanGenerateTwoFactorTokenAsyncData))]
|
||||
public override async Task RunCanGenerateTwoFactorTokenAsync(Dictionary<string, object> metaData, bool expectedResponse,
|
||||
User user, SutProvider<EmailTokenProvider> sutProvider)
|
||||
{
|
||||
await base.RunCanGenerateTwoFactorTokenAsync(metaData, expectedResponse, user, sutProvider);
|
||||
}
|
||||
}
|
||||
}
|
62
test/Core.Test/Identity/U2fTokenProviderTests.cs
Normal file
62
test/Core.Test/Identity/U2fTokenProviderTests.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Identity
|
||||
{
|
||||
public class U2fTokenProviderTests : BaseTokenProviderTests<U2fTokenProvider>
|
||||
{
|
||||
public override TwoFactorProviderType TwoFactorProviderType => TwoFactorProviderType.U2f;
|
||||
|
||||
public static IEnumerable<object[]> CanGenerateTwoFactorTokenAsyncData()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Something"] = "Hello"
|
||||
},
|
||||
true, // canAccessPremium
|
||||
true, // expectedResponse
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
new Dictionary<string, object>(),
|
||||
true, // canAccessPremium
|
||||
false, // expectedResponse
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["Key"] = "Value"
|
||||
},
|
||||
false, // canAccessPremium
|
||||
false, // expectedResponse
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[Theory, BitMemberAutoData(nameof(CanGenerateTwoFactorTokenAsyncData))]
|
||||
public async Task CanGenerateTwoFactorTokenAsync_Success(Dictionary<string, object> metaData, bool canAccessPremium,
|
||||
bool expectedResponse, User user, SutProvider<U2fTokenProvider> sutProvider)
|
||||
{
|
||||
var userManager = SubstituteUserManager();
|
||||
MockDatabase(user, metaData);
|
||||
AdditionalSetup(sutProvider, user)
|
||||
.CanAccessPremium(user)
|
||||
.Returns(canAccessPremium);
|
||||
|
||||
var response = await sutProvider.Sut.CanGenerateTwoFactorTokenAsync(userManager, user);
|
||||
Assert.Equal(expectedResponse, response);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using Bit.Core.Entities;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Test.AutoFixture.CipherFixtures;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Models
|
||||
@ -12,7 +12,7 @@ namespace Bit.Core.Test.Models
|
||||
[InlineOrganizationCipherAutoData]
|
||||
public void Clone_CreatesExactCopy(Cipher cipher)
|
||||
{
|
||||
Assert.Equal(JsonConvert.SerializeObject(cipher), JsonConvert.SerializeObject(cipher.Clone()));
|
||||
Assert.Equal(JsonSerializer.Serialize(cipher), JsonSerializer.Serialize(cipher.Clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
test/Core.Test/Models/Data/SendFileDataTests.cs
Normal file
28
test/Core.Test/Models/Data/SendFileDataTests.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Test.Common.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Models.Data
|
||||
{
|
||||
public class SendFileDataTests
|
||||
{
|
||||
[Fact]
|
||||
public void Serialize_Success()
|
||||
{
|
||||
var sut = new SendFileData
|
||||
{
|
||||
Id = "test",
|
||||
Size = 100,
|
||||
FileName = "thing.pdf",
|
||||
Validated = true,
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(sut);
|
||||
var document = JsonDocument.Parse(json);
|
||||
var root = document.RootElement;
|
||||
AssertHelper.AssertJsonProperty(root, "Size", JsonValueKind.String);
|
||||
Assert.False(root.TryGetProperty("SizeString", out _));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,6 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using AutoFixture.Xunit2;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Models
|
||||
@ -33,21 +29,30 @@ namespace Bit.Core.Test.Models
|
||||
[Fact]
|
||||
public void Serialization_Success()
|
||||
{
|
||||
// minify expected json
|
||||
var expected = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(_exampleSerializedPermissions));
|
||||
|
||||
DefaultContractResolver contractResolver = new DefaultContractResolver
|
||||
var permissions = new Permissions
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy()
|
||||
AccessEventLogs = false,
|
||||
AccessImportExport = false,
|
||||
AccessReports = false,
|
||||
CreateNewCollections = true,
|
||||
EditAnyCollection = true,
|
||||
DeleteAnyCollection = true,
|
||||
EditAssignedCollections = false,
|
||||
DeleteAssignedCollections = false,
|
||||
ManageGroups = false,
|
||||
ManagePolicies = false,
|
||||
ManageSso = false,
|
||||
ManageUsers = false,
|
||||
ManageResetPassword = false,
|
||||
};
|
||||
|
||||
var actual = JsonConvert.SerializeObject(
|
||||
CoreHelpers.LoadClassFromJsonData<Permissions>(_exampleSerializedPermissions), new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = contractResolver,
|
||||
});
|
||||
// minify expected json
|
||||
var expected = JsonSerializer.Serialize(permissions, JsonHelpers.CamelCase);
|
||||
|
||||
var actual = JsonSerializer.Serialize(
|
||||
JsonHelpers.DeserializeOrNew<Permissions>(_exampleSerializedPermissions, JsonHelpers.CamelCase),
|
||||
JsonHelpers.CamelCase);
|
||||
|
||||
Console.WriteLine(actual);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
using Bit.Core.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Test.Common.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Models.Tables
|
||||
@ -39,5 +44,43 @@ namespace Bit.Core.Test.Models.Tables
|
||||
|
||||
Assert.Equal(expectedRemainingBytes, bytesRemaining);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetTwoFactorProviders()
|
||||
{
|
||||
var user = new User();
|
||||
user.SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
[TwoFactorProviderType.WebAuthn] = new TwoFactorProvider
|
||||
{
|
||||
Enabled = true,
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["Item"] = "thing",
|
||||
},
|
||||
},
|
||||
[TwoFactorProviderType.Email] = new TwoFactorProvider
|
||||
{
|
||||
Enabled = false,
|
||||
MetaData = new Dictionary<string, object>
|
||||
{
|
||||
["Email"] = "test@email.com",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
using var jsonDocument = JsonDocument.Parse(user.TwoFactorProviders);
|
||||
var root = jsonDocument.RootElement;
|
||||
|
||||
var webAuthn = AssertHelper.AssertJsonProperty(root, "WebAuthn", JsonValueKind.Object);
|
||||
AssertHelper.AssertJsonProperty(webAuthn, "Enabled", JsonValueKind.True);
|
||||
var webMetaData = AssertHelper.AssertJsonProperty(webAuthn, "MetaData", JsonValueKind.Object);
|
||||
AssertHelper.AssertJsonProperty(webMetaData, "Item", JsonValueKind.String);
|
||||
|
||||
var email = AssertHelper.AssertJsonProperty(root, "Email", JsonValueKind.Object);
|
||||
AssertHelper.AssertJsonProperty(email, "Enabled", JsonValueKind.False);
|
||||
var emailMetaData = AssertHelper.AssertJsonProperty(email, "MetaData", JsonValueKind.Object);
|
||||
AssertHelper.AssertJsonProperty(emailMetaData, "Email", JsonValueKind.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Bit.Test.Common.Helpers;
|
||||
using Fido2NetLib;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
@ -17,103 +24,41 @@ namespace Bit.Core.Test.Services
|
||||
{
|
||||
public class UserServiceTests
|
||||
{
|
||||
private readonly UserService _sut;
|
||||
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IMailService _mailService;
|
||||
private readonly IPushNotificationService _pushService;
|
||||
private readonly IUserStore<User> _userStore;
|
||||
private readonly IOptions<IdentityOptions> _optionsAccessor;
|
||||
private readonly IPasswordHasher<User> _passwordHasher;
|
||||
private readonly IEnumerable<IUserValidator<User>> _userValidators;
|
||||
private readonly IEnumerable<IPasswordValidator<User>> _passwordValidators;
|
||||
private readonly ILookupNormalizer _keyNormalizer;
|
||||
private readonly IdentityErrorDescriber _errors;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger<UserManager<User>> _logger;
|
||||
private readonly ILicensingService _licenseService;
|
||||
private readonly IEventService _eventService;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly IDataProtectionProvider _dataProtectionProvider;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly IFido2 _fido2;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IProviderUserRepository _providerUserRepository;
|
||||
|
||||
public UserServiceTests()
|
||||
[Theory, CustomAutoData(typeof(SutProviderCustomization))]
|
||||
public async Task UpdateLicenseAsync_Success(SutProvider<UserService> sutProvider,
|
||||
User user, UserLicense userLicense)
|
||||
{
|
||||
_userRepository = Substitute.For<IUserRepository>();
|
||||
_cipherRepository = Substitute.For<ICipherRepository>();
|
||||
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
_organizationRepository = Substitute.For<IOrganizationRepository>();
|
||||
_mailService = Substitute.For<IMailService>();
|
||||
_pushService = Substitute.For<IPushNotificationService>();
|
||||
_userStore = Substitute.For<IUserStore<User>>();
|
||||
_optionsAccessor = Substitute.For<IOptions<IdentityOptions>>();
|
||||
_passwordHasher = Substitute.For<IPasswordHasher<User>>();
|
||||
_userValidators = new List<IUserValidator<User>>();
|
||||
_passwordValidators = new List<IPasswordValidator<User>>();
|
||||
_keyNormalizer = Substitute.For<ILookupNormalizer>();
|
||||
_errors = new IdentityErrorDescriber();
|
||||
_services = Substitute.For<IServiceProvider>();
|
||||
_logger = Substitute.For<ILogger<UserManager<User>>>();
|
||||
_licenseService = Substitute.For<ILicensingService>();
|
||||
_eventService = Substitute.For<IEventService>();
|
||||
_applicationCacheService = Substitute.For<IApplicationCacheService>();
|
||||
_dataProtectionProvider = Substitute.For<IDataProtectionProvider>();
|
||||
_paymentService = Substitute.For<IPaymentService>();
|
||||
_policyRepository = Substitute.For<IPolicyRepository>();
|
||||
_referenceEventService = Substitute.For<IReferenceEventService>();
|
||||
_fido2 = Substitute.For<IFido2>();
|
||||
_currentContext = new CurrentContext(null);
|
||||
_globalSettings = new GlobalSettings();
|
||||
_organizationService = Substitute.For<IOrganizationService>();
|
||||
_providerUserRepository = Substitute.For<IProviderUserRepository>();
|
||||
using var tempDir = new TempDirectory();
|
||||
|
||||
_sut = new UserService(
|
||||
_userRepository,
|
||||
_cipherRepository,
|
||||
_organizationUserRepository,
|
||||
_organizationRepository,
|
||||
_mailService,
|
||||
_pushService,
|
||||
_userStore,
|
||||
_optionsAccessor,
|
||||
_passwordHasher,
|
||||
_userValidators,
|
||||
_passwordValidators,
|
||||
_keyNormalizer,
|
||||
_errors,
|
||||
_services,
|
||||
_logger,
|
||||
_licenseService,
|
||||
_eventService,
|
||||
_applicationCacheService,
|
||||
_dataProtectionProvider,
|
||||
_paymentService,
|
||||
_policyRepository,
|
||||
_referenceEventService,
|
||||
_fido2,
|
||||
_currentContext,
|
||||
_globalSettings,
|
||||
_organizationService,
|
||||
_providerUserRepository
|
||||
);
|
||||
}
|
||||
var now = DateTime.UtcNow;
|
||||
userLicense.Issued = now.AddDays(-10);
|
||||
userLicense.Expires = now.AddDays(10);
|
||||
userLicense.Version = 1;
|
||||
userLicense.Premium = true;
|
||||
|
||||
// Remove this test when we add actual tests. It only proves that
|
||||
// we've properly constructed the system under test.
|
||||
[Fact]
|
||||
public void ServiceExists()
|
||||
{
|
||||
Assert.NotNull(_sut);
|
||||
user.EmailVerified = true;
|
||||
user.Email = userLicense.Email;
|
||||
|
||||
sutProvider.GetDependency<Settings.GlobalSettings>().SelfHosted = true;
|
||||
sutProvider.GetDependency<Settings.GlobalSettings>().LicenseDirectory = tempDir.Directory;
|
||||
sutProvider.GetDependency<ILicensingService>()
|
||||
.VerifyLicense(userLicense)
|
||||
.Returns(true);
|
||||
|
||||
await sutProvider.Sut.UpdateLicenseAsync(user, userLicense);
|
||||
|
||||
var filePath = Path.Combine(tempDir.Directory, "user", $"{user.Id}.json");
|
||||
Assert.True(File.Exists(filePath));
|
||||
var document = JsonDocument.Parse(File.OpenRead(filePath));
|
||||
var root = document.RootElement;
|
||||
Assert.Equal(JsonValueKind.Object, root.ValueKind);
|
||||
// Sort of a lazy way to test that it is indented but not sure of a better way
|
||||
Assert.Contains('\n', root.GetRawText());
|
||||
AssertHelper.AssertJsonProperty(root, "LicenseKey", JsonValueKind.String);
|
||||
AssertHelper.AssertJsonProperty(root, "Id", JsonValueKind.String);
|
||||
AssertHelper.AssertJsonProperty(root, "Premium", JsonValueKind.True);
|
||||
var versionProp = AssertHelper.AssertJsonProperty(root, "Version", JsonValueKind.Number);
|
||||
Assert.Equal(1, versionProp.GetInt32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
test/Core.Test/Utilities/JsonHelpersTests.cs
Normal file
66
test/Core.Test/Utilities/JsonHelpersTests.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Utilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Helpers
|
||||
{
|
||||
public class JsonHelpersTests
|
||||
{
|
||||
private static void CompareJson<T>(T value, JsonSerializerOptions options, Newtonsoft.Json.JsonSerializerSettings settings)
|
||||
{
|
||||
var stgJson = JsonSerializer.Serialize(value, options);
|
||||
var nsJson = Newtonsoft.Json.JsonConvert.SerializeObject(value, settings);
|
||||
|
||||
Assert.Equal(stgJson, nsJson);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void DefaultJsonOptions()
|
||||
{
|
||||
var testObject = new SimpleTestObject
|
||||
{
|
||||
Id = 0,
|
||||
Name = "Test",
|
||||
};
|
||||
|
||||
CompareJson(testObject, JsonHelpers.Default, new Newtonsoft.Json.JsonSerializerSettings());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IndentedJsonOptions()
|
||||
{
|
||||
var testObject = new SimpleTestObject
|
||||
{
|
||||
Id = 10,
|
||||
Name = "Test Name"
|
||||
};
|
||||
|
||||
CompareJson(testObject, JsonHelpers.Indented, new Newtonsoft.Json.JsonSerializerSettings
|
||||
{
|
||||
Formatting = Newtonsoft.Json.Formatting.Indented,
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullValueHandlingJsonOptions()
|
||||
{
|
||||
var testObject = new SimpleTestObject
|
||||
{
|
||||
Id = 14,
|
||||
Name = null,
|
||||
};
|
||||
|
||||
CompareJson(testObject, JsonHelpers.IgnoreWritingNull, new Newtonsoft.Json.JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleTestObject
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using Bit.Migrator;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Setup
|
||||
{
|
||||
@ -273,8 +273,9 @@ namespace Bit.Setup
|
||||
}
|
||||
|
||||
var resultString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||
var result = JsonConvert.DeserializeObject<dynamic>(resultString);
|
||||
if (!(bool)result.Enabled)
|
||||
using var jsonDocument = JsonSerializer.Deserialize<JsonDocument>(resultString);
|
||||
var root = jsonDocument.RootElement;
|
||||
if (!root.GetProperty("Enabled").GetBoolean())
|
||||
{
|
||||
Console.WriteLine("Installation id has been disabled.");
|
||||
return false;
|
||||
|
@ -12,7 +12,6 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net" Version="1.10.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="YamlDotNet" Version="8.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user