mirror of
https://github.com/bitwarden/server.git
synced 2024-11-25 12:45:18 +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.Diagnostics;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Admin.Models;
|
using Bit.Admin.Models;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Admin.Controllers
|
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
|
try
|
||||||
{
|
{
|
||||||
var response = await _httpClient.GetAsync(
|
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)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var json = await response.Content.ReadAsStringAsync();
|
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
|
||||||
var data = JObject.Parse(json);
|
var root = jsonDocument.RootElement;
|
||||||
var results = data["results"] as JArray;
|
|
||||||
foreach (var result in results)
|
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]))
|
if (!string.IsNullOrWhiteSpace(name) && name.Length > 0 && char.IsNumber(name[0]))
|
||||||
{
|
{
|
||||||
return new JsonResult(name);
|
return new JsonResult(name);
|
||||||
@ -63,17 +65,17 @@ namespace Bit.Admin.Controllers
|
|||||||
return new JsonResult("-");
|
return new JsonResult("-");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> GetInstalledWebVersion()
|
public async Task<IActionResult> GetInstalledWebVersion(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await _httpClient.GetAsync(
|
var response = await _httpClient.GetAsync(
|
||||||
$"{_globalSettings.BaseServiceUri.InternalVault}/version.json");
|
$"{_globalSettings.BaseServiceUri.InternalVault}/version.json", cancellationToken);
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var json = await response.Content.ReadAsStringAsync();
|
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
|
||||||
var data = JObject.Parse(json);
|
var root = jsonDocument.RootElement;
|
||||||
return new JsonResult(data["version"].ToString());
|
return new JsonResult(root.GetProperty("version").GetString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HttpRequestException) { }
|
catch (HttpRequestException) { }
|
||||||
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Admin.Models;
|
using Bit.Admin.Models;
|
||||||
using Bit.Core;
|
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
@ -14,7 +14,6 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Admin.Controllers
|
namespace Bit.Admin.Controllers
|
||||||
{
|
{
|
||||||
@ -264,14 +263,16 @@ namespace Bit.Admin.Controllers
|
|||||||
{
|
{
|
||||||
var license = await _organizationService.GenerateLicenseAsync(organization,
|
var license = await _organizationService.GenerateLicenseAsync(organization,
|
||||||
model.InstallationId.Value, model.Version);
|
model.InstallationId.Value, model.Version);
|
||||||
return File(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(license, Formatting.Indented)),
|
var ms = new MemoryStream();
|
||||||
"text/plain", "bitwarden_organization_license.json");
|
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
|
||||||
|
return File(ms, "text/plain", "bitwarden_organization_license.json");
|
||||||
}
|
}
|
||||||
else if (user != null)
|
else if (user != null)
|
||||||
{
|
{
|
||||||
var license = await _userService.GenerateLicenseAsync(user, null, model.Version);
|
var license = await _userService.GenerateLicenseAsync(user, null, model.Version);
|
||||||
return File(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(license, Formatting.Indented)),
|
var ms = new MemoryStream();
|
||||||
"text/plain", "bitwarden_premium_license.json");
|
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
|
||||||
|
return File(ms, "text/plain", "bitwarden_premium_license.json");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
@ -11,8 +12,6 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Admin.HostedServices
|
namespace Bit.Admin.HostedServices
|
||||||
{
|
{
|
||||||
@ -70,17 +69,19 @@ namespace Bit.Admin.HostedServices
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var token = JToken.Parse(message.DecodeMessageText());
|
using var document = JsonDocument.Parse(message.DecodeMessageText());
|
||||||
if (token is JArray)
|
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);
|
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);
|
await _mailService.SendEnqueuedMailMessageAsync(mailQueueMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Net.Http.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Admin.HostedServices
|
namespace Bit.Admin.HostedServices
|
||||||
{
|
{
|
||||||
@ -65,7 +64,7 @@ namespace Bit.Admin.HostedServices
|
|||||||
request.RequestUri = new Uri("https://api.cloudflare.com/" +
|
request.RequestUri = new Uri("https://api.cloudflare.com/" +
|
||||||
$"client/v4/zones/{_adminSettings.Cloudflare.ZoneId}/firewall/access_rules/rules");
|
$"client/v4/zones/{_adminSettings.Cloudflare.ZoneId}/firewall/access_rules/rules");
|
||||||
|
|
||||||
var bodyContent = JsonConvert.SerializeObject(new
|
request.Content = JsonContent.Create(new
|
||||||
{
|
{
|
||||||
mode = "block",
|
mode = "block",
|
||||||
configuration = new
|
configuration = new
|
||||||
@ -75,7 +74,6 @@ namespace Bit.Admin.HostedServices
|
|||||||
},
|
},
|
||||||
notes = $"Rate limit abuse on {DateTime.UtcNow.ToString()}."
|
notes = $"Rate limit abuse on {DateTime.UtcNow.ToString()}."
|
||||||
});
|
});
|
||||||
request.Content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
var response = await _httpClient.SendAsync(request, cancellationToken);
|
var response = await _httpClient.SendAsync(request, cancellationToken);
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
@ -83,8 +81,7 @@ namespace Bit.Admin.HostedServices
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseString = await response.Content.ReadAsStringAsync();
|
var accessRuleResponse = await response.Content.ReadFromJsonAsync<AccessRuleResponse>(cancellationToken: cancellationToken);
|
||||||
var accessRuleResponse = JsonConvert.DeserializeObject<AccessRuleResponse>(responseString);
|
|
||||||
if (!accessRuleResponse.Success)
|
if (!accessRuleResponse.Success)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -118,8 +115,7 @@ namespace Bit.Admin.HostedServices
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseString = await response.Content.ReadAsStringAsync();
|
var listResponse = await response.Content.ReadFromJsonAsync<ListResponse>(cancellationToken: cancellationToken);
|
||||||
var listResponse = JsonConvert.DeserializeObject<ListResponse>(responseString);
|
|
||||||
if (!listResponse.Success)
|
if (!listResponse.Success)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Azure.Documents;
|
using Microsoft.Azure.Documents;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Admin.Models
|
namespace Bit.Admin.Models
|
||||||
{
|
{
|
||||||
@ -17,40 +19,48 @@ namespace Bit.Admin.Models
|
|||||||
|
|
||||||
public class LogDetailsModel : LogModel
|
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)
|
if (e == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var val = string.Empty;
|
var root = e.RootElement;
|
||||||
if (e["Message"] != null && e["Message"].ToObject<string>() != null)
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
if (root.TryGetProperty("Message", out var messageProp) && messageProp.GetString() != null)
|
||||||
{
|
{
|
||||||
val += "Message:\n";
|
sb.AppendLine("Message:");
|
||||||
val += e["Message"] + "\n";
|
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";
|
sb.AppendLine();
|
||||||
val += e["StackTrace"];
|
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";
|
sb.AppendLine();
|
||||||
val += e["StackTraceString"];
|
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";
|
sb.AppendLine();
|
||||||
val += ExceptionToString(e["InnerException"].ToObject<JObject>());
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Messaging.EventGrid;
|
using Azure.Messaging.EventGrid;
|
||||||
using Bit.Api.Models.Request;
|
using Bit.Api.Models.Request;
|
||||||
@ -21,7 +22,6 @@ using Core.Models.Data;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Controllers
|
namespace Bit.Api.Controllers
|
||||||
{
|
{
|
||||||
@ -802,7 +802,7 @@ namespace Bit.Api.Controllers
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Api.Models.Request;
|
using Bit.Api.Models.Request;
|
||||||
using Bit.Api.Models.Request.Accounts;
|
using Bit.Api.Models.Request.Accounts;
|
||||||
@ -17,7 +18,6 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Controllers
|
namespace Bit.Api.Controllers
|
||||||
{
|
{
|
||||||
@ -185,7 +185,7 @@ namespace Bit.Api.Controllers
|
|||||||
return new OrganizationAutoEnrollStatusResponseModel(organization.Id, false);
|
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);
|
return new OrganizationAutoEnrollStatusResponseModel(organization.Id, data?.AutoEnrollEnabled ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Messaging.EventGrid;
|
using Azure.Messaging.EventGrid;
|
||||||
using Bit.Api.Models.Request;
|
using Bit.Api.Models.Request;
|
||||||
@ -19,7 +20,6 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Controllers
|
namespace Bit.Api.Controllers
|
||||||
{
|
{
|
||||||
@ -227,7 +227,7 @@ namespace Bit.Api.Controllers
|
|||||||
var userId = _userService.GetProperUserId(User).Value;
|
var userId = _userService.GetProperUserId(User).Value;
|
||||||
var sendId = new Guid(id);
|
var sendId = new Guid(id);
|
||||||
var send = await _sendRepository.GetByIdAsync(sendId);
|
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) ||
|
if (send == null || send.Type != SendType.File || (send.UserId.HasValue && send.UserId.Value != userId) ||
|
||||||
!send.UserId.HasValue || fileData.Id != fileId || fileData.Validated)
|
!send.UserId.HasValue || fileData.Id != fileId || fileData.Validated)
|
||||||
@ -289,7 +289,7 @@ namespace Bit.Api.Controllers
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Public.Request
|
namespace Bit.Api.Models.Public.Request
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ namespace Bit.Api.Models.Public.Request
|
|||||||
public virtual Policy ToPolicy(Policy existingPolicy)
|
public virtual Policy ToPolicy(Policy existingPolicy)
|
||||||
{
|
{
|
||||||
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
existingPolicy.Enabled = Enabled.GetValueOrDefault();
|
||||||
existingPolicy.Data = Data != null ? JsonConvert.SerializeObject(Data) : null;
|
existingPolicy.Data = Data != null ? JsonSerializer.Serialize(Data) : null;
|
||||||
return existingPolicy;
|
return existingPolicy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Public.Response
|
namespace Bit.Api.Models.Public.Response
|
||||||
{
|
{
|
||||||
@ -24,7 +25,7 @@ namespace Bit.Api.Models.Public.Response
|
|||||||
Enabled = policy.Enabled;
|
Enabled = policy.Enabled;
|
||||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
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.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
using Newtonsoft.Json;
|
using NS = Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using NSL = Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request
|
namespace Bit.Api.Models.Request
|
||||||
{
|
{
|
||||||
@ -69,22 +70,20 @@ namespace Bit.Api.Models.Request
|
|||||||
switch (existingCipher.Type)
|
switch (existingCipher.Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
var loginObj = JObject.FromObject(ToCipherLoginData(),
|
var loginObj = NSL.JObject.FromObject(ToCipherLoginData(),
|
||||||
new JsonSerializer { NullValueHandling = NullValueHandling.Ignore });
|
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();
|
loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove();
|
||||||
existingCipher.Data = loginObj.ToString(Formatting.None);
|
existingCipher.Data = loginObj.ToString(NS.Formatting.None);
|
||||||
break;
|
break;
|
||||||
case CipherType.Card:
|
case CipherType.Card:
|
||||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherCardData(),
|
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
break;
|
break;
|
||||||
case CipherType.Identity:
|
case CipherType.Identity:
|
||||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherIdentityData(),
|
existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
existingCipher.Data = JsonConvert.SerializeObject(ToCipherSecureNoteData(),
|
existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request
|
namespace Bit.Api.Models.Request
|
||||||
{
|
{
|
||||||
@ -65,15 +65,13 @@ namespace Bit.Api.Models.Request
|
|||||||
switch (existingSend.Type)
|
switch (existingSend.Type)
|
||||||
{
|
{
|
||||||
case SendType.File:
|
case SendType.File:
|
||||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(existingSend.Data);
|
var fileData = JsonSerializer.Deserialize<SendFileData>(existingSend.Data);
|
||||||
fileData.Name = Name;
|
fileData.Name = Name;
|
||||||
fileData.Notes = Notes;
|
fileData.Notes = Notes;
|
||||||
existingSend.Data = JsonConvert.SerializeObject(fileData,
|
existingSend.Data = JsonSerializer.Serialize(fileData, JsonHelpers.IgnoreWritingNull);
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
break;
|
break;
|
||||||
case SendType.Text:
|
case SendType.Text:
|
||||||
existingSend.Data = JsonConvert.SerializeObject(ToSendData(),
|
existingSend.Data = JsonSerializer.Serialize(ToSendData(), JsonHelpers.IgnoreWritingNull);
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request
|
namespace Bit.Api.Models.Request
|
||||||
{
|
{
|
||||||
@ -12,9 +12,9 @@ namespace Bit.Api.Models.Request
|
|||||||
|
|
||||||
public User ToUser(User existingUser)
|
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 ?
|
existingUser.ExcludedGlobalEquivalentDomains = ExcludedGlobalEquivalentDomains != null ?
|
||||||
JsonConvert.SerializeObject(ExcludedGlobalEquivalentDomains) : null;
|
JsonSerializer.Serialize(ExcludedGlobalEquivalentDomains) : null;
|
||||||
return existingUser;
|
return existingUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
@ -18,7 +19,7 @@ namespace Bit.Api.Models.Response
|
|||||||
Url = $"{globalSettings.Attachment.BaseUrl}/{cipher.Id}/{id}";
|
Url = $"{globalSettings.Attachment.BaseUrl}/{cipher.Id}/{id}";
|
||||||
FileName = data.FileName;
|
FileName = data.FileName;
|
||||||
Key = data.Key;
|
Key = data.Key;
|
||||||
Size = data.SizeString;
|
Size = data.Size;
|
||||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ namespace Bit.Api.Models.Response
|
|||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
public string Key { 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 string SizeName { get; set; }
|
||||||
|
|
||||||
public static IEnumerable<AttachmentResponseModel> FromCipher(Cipher cipher, IGlobalSettings globalSettings)
|
public static IEnumerable<AttachmentResponseModel> FromCipher(Cipher cipher, IGlobalSettings globalSettings)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Api.Models.Response
|
||||||
{
|
{
|
||||||
@ -28,25 +28,25 @@ namespace Bit.Api.Models.Response
|
|||||||
switch (cipher.Type)
|
switch (cipher.Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
var loginData = JsonConvert.DeserializeObject<CipherLoginData>(cipher.Data);
|
var loginData = JsonSerializer.Deserialize<CipherLoginData>(cipher.Data);
|
||||||
cipherData = loginData;
|
cipherData = loginData;
|
||||||
Data = loginData;
|
Data = loginData;
|
||||||
Login = new CipherLoginModel(loginData);
|
Login = new CipherLoginModel(loginData);
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
var secureNoteData = JsonConvert.DeserializeObject<CipherSecureNoteData>(cipher.Data);
|
var secureNoteData = JsonSerializer.Deserialize<CipherSecureNoteData>(cipher.Data);
|
||||||
Data = secureNoteData;
|
Data = secureNoteData;
|
||||||
cipherData = secureNoteData;
|
cipherData = secureNoteData;
|
||||||
SecureNote = new CipherSecureNoteModel(secureNoteData);
|
SecureNote = new CipherSecureNoteModel(secureNoteData);
|
||||||
break;
|
break;
|
||||||
case CipherType.Card:
|
case CipherType.Card:
|
||||||
var cardData = JsonConvert.DeserializeObject<CipherCardData>(cipher.Data);
|
var cardData = JsonSerializer.Deserialize<CipherCardData>(cipher.Data);
|
||||||
Data = cardData;
|
Data = cardData;
|
||||||
cipherData = cardData;
|
cipherData = cardData;
|
||||||
Card = new CipherCardModel(cardData);
|
Card = new CipherCardModel(cardData);
|
||||||
break;
|
break;
|
||||||
case CipherType.Identity:
|
case CipherType.Identity:
|
||||||
var identityData = JsonConvert.DeserializeObject<CipherIdentityData>(cipher.Data);
|
var identityData = JsonSerializer.Deserialize<CipherIdentityData>(cipher.Data);
|
||||||
Data = identityData;
|
Data = identityData;
|
||||||
cipherData = identityData;
|
cipherData = identityData;
|
||||||
Identity = new CipherIdentityModel(identityData);
|
Identity = new CipherIdentityModel(identityData);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Api.Models.Response
|
||||||
{
|
{
|
||||||
@ -19,10 +19,10 @@ namespace Bit.Api.Models.Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
EquivalentDomains = user.EquivalentDomains != null ?
|
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 ?
|
var excludedGlobalEquivalentDomains = user.ExcludedGlobalEquivalentDomains != null ?
|
||||||
JsonConvert.DeserializeObject<List<GlobalEquivalentDomainsType>>(user.ExcludedGlobalEquivalentDomains) :
|
JsonSerializer.Deserialize<List<GlobalEquivalentDomainsType>>(user.ExcludedGlobalEquivalentDomains) :
|
||||||
new List<GlobalEquivalentDomainsType>();
|
new List<GlobalEquivalentDomainsType>();
|
||||||
var globalDomains = new List<GlobalDomains>();
|
var globalDomains = new List<GlobalDomains>();
|
||||||
var domainsToInclude = excluded ? Core.Utilities.StaticStore.GlobalDomains :
|
var domainsToInclude = excluded ? Core.Utilities.StaticStore.GlobalDomains :
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Api.Models.Response
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ namespace Bit.Api.Models.Response
|
|||||||
Enabled = policy.Enabled;
|
Enabled = policy.Enabled;
|
||||||
if (!string.IsNullOrWhiteSpace(policy.Data))
|
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;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Api.Models.Response
|
||||||
{
|
{
|
||||||
@ -26,12 +26,12 @@ namespace Bit.Api.Models.Response
|
|||||||
switch (send.Type)
|
switch (send.Type)
|
||||||
{
|
{
|
||||||
case SendType.File:
|
case SendType.File:
|
||||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
var fileData = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||||
sendData = fileData;
|
sendData = fileData;
|
||||||
File = new SendFileModel(fileData);
|
File = new SendFileModel(fileData);
|
||||||
break;
|
break;
|
||||||
case SendType.Text:
|
case SendType.Text:
|
||||||
var textData = JsonConvert.DeserializeObject<SendTextData>(send.Data);
|
var textData = JsonSerializer.Deserialize<SendTextData>(send.Data);
|
||||||
sendData = textData;
|
sendData = textData;
|
||||||
Text = new SendTextModel(textData);
|
Text = new SendTextModel(textData);
|
||||||
break;
|
break;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Api.Models.Response
|
||||||
{
|
{
|
||||||
@ -36,12 +36,12 @@ namespace Bit.Api.Models.Response
|
|||||||
switch (send.Type)
|
switch (send.Type)
|
||||||
{
|
{
|
||||||
case SendType.File:
|
case SendType.File:
|
||||||
var fileData = JsonConvert.DeserializeObject<SendFileData>(send.Data);
|
var fileData = JsonSerializer.Deserialize<SendFileData>(send.Data);
|
||||||
sendData = fileData;
|
sendData = fileData;
|
||||||
File = new SendFileModel(fileData);
|
File = new SendFileModel(fileData);
|
||||||
break;
|
break;
|
||||||
case SendType.Text:
|
case SendType.Text:
|
||||||
var textData = JsonConvert.DeserializeObject<SendTextData>(send.Data);
|
var textData = JsonSerializer.Deserialize<SendTextData>(send.Data);
|
||||||
sendData = textData;
|
sendData = textData;
|
||||||
Text = new SendTextModel(textData);
|
Text = new SendTextModel(textData);
|
||||||
break;
|
break;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Models.Data;
|
using System.Text.Json.Serialization;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Api.Models
|
namespace Bit.Api.Models
|
||||||
@ -11,7 +12,7 @@ namespace Bit.Api.Models
|
|||||||
{
|
{
|
||||||
Id = data.Id;
|
Id = data.Id;
|
||||||
FileName = data.FileName;
|
FileName = data.FileName;
|
||||||
Size = data.SizeString;
|
Size = data.Size;
|
||||||
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
SizeName = CoreHelpers.ReadableBytesSize(data.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +20,8 @@ namespace Bit.Api.Models
|
|||||||
[EncryptedString]
|
[EncryptedString]
|
||||||
[EncryptedStringLength(1000)]
|
[EncryptedStringLength(1000)]
|
||||||
public string FileName { get; set; }
|
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; }
|
public string SizeName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Messaging.EventGrid;
|
using Azure.Messaging.EventGrid;
|
||||||
using Azure.Messaging.EventGrid.SystemEvents;
|
using Azure.Messaging.EventGrid.SystemEvents;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Utilities
|
namespace Bit.Api.Utilities
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ namespace Bit.Api.Utilities
|
|||||||
var s = await reader.ReadToEndAsync();
|
var s = await reader.ReadToEndAsync();
|
||||||
if (!string.IsNullOrWhiteSpace(s))
|
if (!string.IsNullOrWhiteSpace(s))
|
||||||
{
|
{
|
||||||
obj = JsonConvert.DeserializeObject<T>(s);
|
obj = JsonSerializer.Deserialize<T>(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Api.Models.Request;
|
using Bit.Api.Models.Request;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -7,7 +8,6 @@ using Microsoft.AspNetCore.Http.Features;
|
|||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Api.Utilities
|
namespace Bit.Api.Utilities
|
||||||
{
|
{
|
||||||
@ -78,13 +78,6 @@ namespace Bit.Api.Utilities
|
|||||||
{
|
{
|
||||||
if (ContentDispositionHeaderValue.TryParse(firstSection.ContentDisposition, out _))
|
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();
|
var secondSection = await reader.ReadNextSectionAsync();
|
||||||
if (secondSection != null)
|
if (secondSection != null)
|
||||||
{
|
{
|
||||||
@ -94,7 +87,7 @@ namespace Bit.Api.Utilities
|
|||||||
var fileName = HeaderUtilities.RemoveQuotes(secondContent.FileName).ToString();
|
var fileName = HeaderUtilities.RemoveQuotes(secondContent.FileName).ToString();
|
||||||
using (secondSection.Body)
|
using (secondSection.Body)
|
||||||
{
|
{
|
||||||
var model = JsonConvert.DeserializeObject<SendRequestModel>(requestModelJson);
|
var model = await JsonSerializer.DeserializeAsync<SendRequestModel>(firstSection.Body);
|
||||||
await callback(secondSection.Body, fileName, model);
|
await callback(secondSection.Body, fileName, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Billing.Controllers
|
namespace Bit.Billing.Controllers
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@ namespace Bit.Billing.Controllers
|
|||||||
|
|
||||||
try
|
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);
|
_logger.LogInformation(Constants.BypassFiltersEventId, "Apple IAP Notification:\n\n{0}", json);
|
||||||
return new OkResult();
|
return new OkResult();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
@ -13,7 +14,6 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Billing.Controllers
|
namespace Bit.Billing.Controllers
|
||||||
{
|
{
|
||||||
@ -62,23 +62,18 @@ namespace Bit.Billing.Controllers
|
|||||||
return new BadRequestResult();
|
return new BadRequestResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
string body = null;
|
using var body = await JsonSerializer.DeserializeAsync<JsonDocument>(HttpContext.Request.Body);
|
||||||
using (var reader = new StreamReader(HttpContext.Request.Body, Encoding.UTF8))
|
var root = body.RootElement;
|
||||||
{
|
if (root.ValueKind != JsonValueKind.Object)
|
||||||
body = await reader.ReadToEndAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(body))
|
|
||||||
{
|
{
|
||||||
return new BadRequestResult();
|
return new BadRequestResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dynamic data = JsonConvert.DeserializeObject(body);
|
var ticketId = root.GetProperty("ticket_id").GetString();
|
||||||
string ticketId = data.ticket_id;
|
var ticketContactEmail = root.GetProperty("ticket_contact_email").GetString();
|
||||||
string ticketContactEmail = data.ticket_contact_email;
|
var ticketTags = root.GetProperty("ticket_tags").GetString();
|
||||||
string ticketTags = data.ticket_tags;
|
|
||||||
if (string.IsNullOrWhiteSpace(ticketId) || string.IsNullOrWhiteSpace(ticketContactEmail))
|
if (string.IsNullOrWhiteSpace(ticketId) || string.IsNullOrWhiteSpace(ticketContactEmail))
|
||||||
{
|
{
|
||||||
return new BadRequestResult();
|
return new BadRequestResult();
|
||||||
@ -120,9 +115,11 @@ namespace Bit.Billing.Controllers
|
|||||||
updateBody.Add("tags", tagsToUpdate);
|
updateBody.Add("tags", tagsToUpdate);
|
||||||
}
|
}
|
||||||
var updateRequest = new HttpRequestMessage(HttpMethod.Put,
|
var updateRequest = new HttpRequestMessage(HttpMethod.Put,
|
||||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId));
|
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId))
|
||||||
updateRequest.Content = new StringContent(JsonConvert.SerializeObject(updateBody),
|
{
|
||||||
Encoding.UTF8, "application/json");
|
Content = JsonContent.Create(updateBody),
|
||||||
|
};
|
||||||
|
|
||||||
await CallFreshdeskApiAsync(updateRequest);
|
await CallFreshdeskApiAsync(updateRequest);
|
||||||
|
|
||||||
|
|
||||||
@ -132,9 +129,10 @@ namespace Bit.Billing.Controllers
|
|||||||
{ "private", true }
|
{ "private", true }
|
||||||
};
|
};
|
||||||
var noteRequest = new HttpRequestMessage(HttpMethod.Post,
|
var noteRequest = new HttpRequestMessage(HttpMethod.Post,
|
||||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}/notes", ticketId));
|
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}/notes", ticketId))
|
||||||
noteRequest.Content = new StringContent(JsonConvert.SerializeObject(noteBody),
|
{
|
||||||
Encoding.UTF8, "application/json");
|
Content = JsonContent.Create(noteBody),
|
||||||
|
};
|
||||||
await CallFreshdeskApiAsync(noteRequest);
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Entities
|
namespace Bit.Core.Entities
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ namespace Bit.Core.Entities
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_attachmentData = JsonConvert.DeserializeObject<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
|
_attachmentData = JsonSerializer.Deserialize<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
|
||||||
foreach (var kvp in _attachmentData)
|
foreach (var kvp in _attachmentData)
|
||||||
{
|
{
|
||||||
kvp.Value.AttachmentId = kvp.Key;
|
kvp.Value.AttachmentId = kvp.Key;
|
||||||
@ -65,7 +65,7 @@ namespace Bit.Core.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
_attachmentData = data;
|
_attachmentData = data;
|
||||||
Attachments = JsonConvert.SerializeObject(_attachmentData);
|
Attachments = JsonSerializer.Serialize(_attachmentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddAttachment(string id, CipherAttachment.MetaData data)
|
public void AddAttachment(string id, CipherAttachment.MetaData data)
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Entities
|
namespace Bit.Core.Entities
|
||||||
{
|
{
|
||||||
@ -142,13 +142,13 @@ namespace Bit.Core.Entities
|
|||||||
if (_twoFactorProviders == null)
|
if (_twoFactorProviders == null)
|
||||||
{
|
{
|
||||||
_twoFactorProviders =
|
_twoFactorProviders =
|
||||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
JsonSerializer.Deserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||||
TwoFactorProviders);
|
TwoFactorProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _twoFactorProviders;
|
return _twoFactorProviders;
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -163,10 +163,7 @@ namespace Bit.Core.Entities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TwoFactorProviders = JsonConvert.SerializeObject(providers, new JsonSerializerSettings
|
TwoFactorProviders = JsonSerializer.Serialize(providers);
|
||||||
{
|
|
||||||
ContractResolver = new EnumKeyResolver<byte>()
|
|
||||||
});
|
|
||||||
_twoFactorProviders = providers;
|
_twoFactorProviders = providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Entities
|
namespace Bit.Core.Entities
|
||||||
{
|
{
|
||||||
@ -108,13 +108,13 @@ namespace Bit.Core.Entities
|
|||||||
if (_twoFactorProviders == null)
|
if (_twoFactorProviders == null)
|
||||||
{
|
{
|
||||||
_twoFactorProviders =
|
_twoFactorProviders =
|
||||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||||
TwoFactorProviders);
|
TwoFactorProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _twoFactorProviders;
|
return _twoFactorProviders;
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -132,10 +132,7 @@ namespace Bit.Core.Entities
|
|||||||
|
|
||||||
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
|
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
|
||||||
{
|
{
|
||||||
TwoFactorProviders = JsonConvert.SerializeObject(providers, new JsonSerializerSettings
|
TwoFactorProviders = JsonHelpers.LegacySerialize(providers);
|
||||||
{
|
|
||||||
ContractResolver = new EnumKeyResolver<byte>()
|
|
||||||
});
|
|
||||||
_twoFactorProviders = providers;
|
_twoFactorProviders = providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -10,7 +11,6 @@ using Bit.Core.Services;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using U2F.Core.Exceptions;
|
using U2F.Core.Exceptions;
|
||||||
using U2F.Core.Models;
|
using U2F.Core.Models;
|
||||||
using U2F.Core.Utils;
|
using U2F.Core.Utils;
|
||||||
@ -107,8 +107,8 @@ namespace Bit.Core.Identity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldToken = JsonConvert.SerializeObject(oldChallenges);
|
var oldToken = JsonSerializer.Serialize(oldChallenges);
|
||||||
var token = JsonConvert.SerializeObject(new
|
var token = JsonSerializer.Serialize(new
|
||||||
{
|
{
|
||||||
appId = appId,
|
appId = appId,
|
||||||
challenge = challengeBytes.ByteArrayToBase64String(),
|
challenge = challengeBytes.ByteArrayToBase64String(),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -12,7 +13,6 @@ using Fido2NetLib;
|
|||||||
using Fido2NetLib.Objects;
|
using Fido2NetLib.Objects;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Identity
|
namespace Bit.Core.Identity
|
||||||
{
|
{
|
||||||
@ -98,7 +98,7 @@ namespace Bit.Core.Identity
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientResponse = JsonConvert.DeserializeObject<AuthenticatorAssertionRawResponse>(token);
|
var clientResponse = JsonSerializer.Deserialize<AuthenticatorAssertionRawResponse>(token);
|
||||||
|
|
||||||
var jsonOptions = provider.MetaData["login"].ToString();
|
var jsonOptions = provider.MetaData["login"].ToString();
|
||||||
var options = AssertionOptions.FromJson(jsonOptions);
|
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;">
|
<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">
|
<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 you do not wish to join this organization, you can safely ignore this email.
|
||||||
{{#if OrganizationCanSponsor}}
|
{{#jsonIf OrganizationCanSponsor}}
|
||||||
<p style="margin-top:10px">
|
<p style="margin-top:10px">
|
||||||
<b
|
<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;">
|
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
|
Members of {{OrganizationName}} receive a complimentary Families subscription. Learn more at the
|
||||||
following link: https://bitwarden.com/help/article/families-for-enterprise/
|
following link: https://bitwarden.com/help/article/families-for-enterprise/
|
||||||
</p>
|
</p>
|
||||||
{{/if}}
|
{{/jsonIf}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -6,7 +6,7 @@ You have been invited to join the {{OrganizationName}} organization. To accept t
|
|||||||
This link expires on {{ExpirationDate}}.
|
This link expires on {{ExpirationDate}}.
|
||||||
|
|
||||||
If you do not wish to join this organization, you can safely ignore this email.
|
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/
|
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}}
|
{{/BasicTextLayout}}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Api.Request.Accounts
|
namespace Bit.Core.Models.Api.Request.Accounts
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace Bit.Core.Models.Api.Request.Accounts
|
|||||||
|
|
||||||
if (ReferenceData != null)
|
if (ReferenceData != null)
|
||||||
{
|
{
|
||||||
user.ReferenceData = JsonConvert.SerializeObject(ReferenceData);
|
user.ReferenceData = JsonSerializer.Serialize(ReferenceData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Key != null)
|
if (Key != null)
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
|
|
||||||
namespace Bit.Billing.Models
|
namespace Bit.Billing.Models
|
||||||
{
|
{
|
||||||
public class AppleReceiptStatus
|
public class AppleReceiptStatus
|
||||||
{
|
{
|
||||||
[JsonProperty("status")]
|
[JsonPropertyName("status")]
|
||||||
public int? Status { get; set; }
|
public int? Status { get; set; }
|
||||||
[JsonProperty("environment")]
|
[JsonPropertyName("environment")]
|
||||||
public string Environment { get; set; }
|
public string Environment { get; set; }
|
||||||
[JsonProperty("latest_receipt")]
|
[JsonPropertyName("latest_receipt")]
|
||||||
public string LatestReceipt { get; set; }
|
public string LatestReceipt { get; set; }
|
||||||
[JsonProperty("receipt")]
|
[JsonPropertyName("receipt")]
|
||||||
public AppleReceipt Receipt { get; set; }
|
public AppleReceipt Receipt { get; set; }
|
||||||
[JsonProperty("latest_receipt_info")]
|
[JsonPropertyName("latest_receipt_info")]
|
||||||
public List<AppleTransaction> LatestReceiptInfo { get; set; }
|
public List<AppleTransaction> LatestReceiptInfo { get; set; }
|
||||||
[JsonProperty("pending_renewal_info")]
|
[JsonPropertyName("pending_renewal_info")]
|
||||||
public List<AppleRenewalInfo> PendingRenewalInfo { get; set; }
|
public List<AppleRenewalInfo> PendingRenewalInfo { get; set; }
|
||||||
|
|
||||||
public string GetOriginalTransactionId()
|
public string GetOriginalTransactionId()
|
||||||
@ -81,72 +82,59 @@ namespace Bit.Billing.Models
|
|||||||
|
|
||||||
public class AppleReceipt
|
public class AppleReceipt
|
||||||
{
|
{
|
||||||
[JsonProperty("receipt_type")]
|
[JsonPropertyName("receipt_type")]
|
||||||
public string ReceiptType { get; set; }
|
public string ReceiptType { get; set; }
|
||||||
[JsonProperty("bundle_id")]
|
[JsonPropertyName("bundle_id")]
|
||||||
public string BundleId { get; set; }
|
public string BundleId { get; set; }
|
||||||
[JsonProperty("receipt_creation_date_ms")]
|
[JsonPropertyName("receipt_creation_date_ms")]
|
||||||
[JsonConverter(typeof(MsEpochConverter))]
|
[JsonConverter(typeof(MsEpochConverter))]
|
||||||
public DateTime ReceiptCreationDate { get; set; }
|
public DateTime ReceiptCreationDate { get; set; }
|
||||||
[JsonProperty("in_app")]
|
[JsonPropertyName("in_app")]
|
||||||
public List<AppleTransaction> InApp { get; set; }
|
public List<AppleTransaction> InApp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppleRenewalInfo
|
public class AppleRenewalInfo
|
||||||
{
|
{
|
||||||
[JsonProperty("expiration_intent")]
|
[JsonPropertyName("expiration_intent")]
|
||||||
public string ExpirationIntent { get; set; }
|
public string ExpirationIntent { get; set; }
|
||||||
[JsonProperty("auto_renew_product_id")]
|
[JsonPropertyName("auto_renew_product_id")]
|
||||||
public string AutoRenewProductId { get; set; }
|
public string AutoRenewProductId { get; set; }
|
||||||
[JsonProperty("original_transaction_id")]
|
[JsonPropertyName("original_transaction_id")]
|
||||||
public string OriginalTransactionId { get; set; }
|
public string OriginalTransactionId { get; set; }
|
||||||
[JsonProperty("is_in_billing_retry_period")]
|
[JsonPropertyName("is_in_billing_retry_period")]
|
||||||
public string IsInBillingRetryPeriod { get; set; }
|
public string IsInBillingRetryPeriod { get; set; }
|
||||||
[JsonProperty("product_id")]
|
[JsonPropertyName("product_id")]
|
||||||
public string ProductId { get; set; }
|
public string ProductId { get; set; }
|
||||||
[JsonProperty("auto_renew_status")]
|
[JsonPropertyName("auto_renew_status")]
|
||||||
public string AutoRenewStatus { get; set; }
|
public string AutoRenewStatus { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppleTransaction
|
public class AppleTransaction
|
||||||
{
|
{
|
||||||
[JsonProperty("quantity")]
|
[JsonPropertyName("quantity")]
|
||||||
public string Quantity { get; set; }
|
public string Quantity { get; set; }
|
||||||
[JsonProperty("product_id")]
|
[JsonPropertyName("product_id")]
|
||||||
public string ProductId { get; set; }
|
public string ProductId { get; set; }
|
||||||
[JsonProperty("transaction_id")]
|
[JsonPropertyName("transaction_id")]
|
||||||
public string TransactionId { get; set; }
|
public string TransactionId { get; set; }
|
||||||
[JsonProperty("original_transaction_id")]
|
[JsonPropertyName("original_transaction_id")]
|
||||||
public string OriginalTransactionId { get; set; }
|
public string OriginalTransactionId { get; set; }
|
||||||
[JsonProperty("purchase_date_ms")]
|
[JsonPropertyName("purchase_date_ms")]
|
||||||
[JsonConverter(typeof(MsEpochConverter))]
|
[JsonConverter(typeof(MsEpochConverter))]
|
||||||
public DateTime PurchaseDate { get; set; }
|
public DateTime PurchaseDate { get; set; }
|
||||||
[JsonProperty("original_purchase_date_ms")]
|
[JsonPropertyName("original_purchase_date_ms")]
|
||||||
[JsonConverter(typeof(MsEpochConverter))]
|
[JsonConverter(typeof(MsEpochConverter))]
|
||||||
public DateTime OriginalPurchaseDate { get; set; }
|
public DateTime OriginalPurchaseDate { get; set; }
|
||||||
[JsonProperty("expires_date_ms")]
|
[JsonPropertyName("expires_date_ms")]
|
||||||
[JsonConverter(typeof(MsEpochConverter))]
|
[JsonConverter(typeof(MsEpochConverter))]
|
||||||
public DateTime ExpiresDate { get; set; }
|
public DateTime ExpiresDate { get; set; }
|
||||||
[JsonProperty("cancellation_date_ms")]
|
[JsonPropertyName("cancellation_date_ms")]
|
||||||
[JsonConverter(typeof(MsEpochConverter))]
|
[JsonConverter(typeof(MsEpochConverter))]
|
||||||
public DateTime? CancellationDate { get; set; }
|
public DateTime? CancellationDate { get; set; }
|
||||||
[JsonProperty("web_order_line_item_id")]
|
[JsonPropertyName("web_order_line_item_id")]
|
||||||
public string WebOrderLineItemId { get; set; }
|
public string WebOrderLineItemId { get; set; }
|
||||||
[JsonProperty("cancellation_reason")]
|
[JsonPropertyName("cancellation_reason")]
|
||||||
public string CancellationReason { get; set; }
|
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;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Business
|
namespace Bit.Core.Models.Business
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using Newtonsoft.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Business
|
namespace Bit.Core.Models.Business
|
||||||
{
|
{
|
||||||
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
|
|
||||||
public class ReferenceEvent
|
public class ReferenceEvent
|
||||||
{
|
{
|
||||||
public ReferenceEvent() { }
|
public ReferenceEvent() { }
|
||||||
@ -23,10 +20,10 @@ namespace Bit.Core.Models.Business
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public ReferenceEventType Type { get; set; }
|
public ReferenceEventType Type { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public ReferenceEventSource Source { get; set; }
|
public ReferenceEventSource Source { get; set; }
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
@ -52,7 +49,7 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public short? Storage { get; set; }
|
public short? Storage { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public SendType? SendType { get; set; }
|
public SendType? SendType { get; set; }
|
||||||
|
|
||||||
public int? MaxAccessCount { 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;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Business
|
namespace Bit.Core.Models.Business
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
@ -15,21 +15,14 @@ namespace Bit.Core.Models.Data
|
|||||||
{
|
{
|
||||||
private long _size;
|
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
|
public long Size
|
||||||
{
|
{
|
||||||
get { return _size; }
|
get { return _size; }
|
||||||
set { _size = value; }
|
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 FileName { get; set; }
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
@ -37,13 +38,13 @@ namespace Bit.Core.Models.Data
|
|||||||
if (_twoFactorProviders == null)
|
if (_twoFactorProviders == null)
|
||||||
{
|
{
|
||||||
_twoFactorProviders =
|
_twoFactorProviders =
|
||||||
JsonConvert.DeserializeObject<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
|
||||||
TwoFactorProviders);
|
TwoFactorProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _twoFactorProviders;
|
return _twoFactorProviders;
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException)
|
catch (Newtonsoft.Json.JsonException)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
@ -25,7 +25,6 @@ namespace Bit.Core.Models.Data
|
|||||||
public bool ManageResetPassword { get; set; }
|
public bool ManageResetPassword { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[System.Text.Json.Serialization.JsonIgnore]
|
|
||||||
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
|
public List<(bool Permission, string ClaimName)> ClaimsMap => new()
|
||||||
{
|
{
|
||||||
(AccessEventLogs, "accesseventlogs"),
|
(AccessEventLogs, "accesseventlogs"),
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
public class SendFileData : SendData
|
public class SendFileData : SendData
|
||||||
{
|
{
|
||||||
private long _size;
|
|
||||||
|
|
||||||
public SendFileData() { }
|
public SendFileData() { }
|
||||||
|
|
||||||
public SendFileData(string name, string notes, string fileName)
|
public SendFileData(string name, string notes, string fileName)
|
||||||
@ -15,20 +13,9 @@ namespace Bit.Core.Models.Data
|
|||||||
FileName = fileName;
|
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
|
// We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers
|
||||||
[JsonProperty("Size")]
|
[JsonNumberHandling(JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString)]
|
||||||
public string SizeString
|
public long Size { get; set; }
|
||||||
{
|
|
||||||
get { return _size.ToString(); }
|
|
||||||
set { _size = Convert.ToInt64(value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
|
@ -9,6 +9,6 @@ namespace Bit.Core.Models.Mail
|
|||||||
IEnumerable<string> BccEmails { get; set; }
|
IEnumerable<string> BccEmails { get; set; }
|
||||||
string Category { get; set; }
|
string Category { get; set; }
|
||||||
string TemplateName { get; set; }
|
string TemplateName { get; set; }
|
||||||
dynamic Model { get; set; }
|
object Model { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Mail
|
namespace Bit.Core.Models.Mail
|
||||||
{
|
{
|
||||||
@ -11,12 +11,13 @@ namespace Bit.Core.Models.Mail
|
|||||||
public IEnumerable<string> BccEmails { get; set; }
|
public IEnumerable<string> BccEmails { get; set; }
|
||||||
public string Category { get; set; }
|
public string Category { get; set; }
|
||||||
public string TemplateName { 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() { }
|
||||||
|
|
||||||
public MailQueueMessage(MailMessage message, string templateName, dynamic model)
|
public MailQueueMessage(MailMessage message, string templateName, object model)
|
||||||
{
|
{
|
||||||
Subject = message.Subject;
|
Subject = message.Subject;
|
||||||
ToEmails = message.ToEmails;
|
ToEmails = message.ToEmails;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using Fido2NetLib.Objects;
|
using Fido2NetLib.Objects;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using PeterO.Cbor;
|
using PeterO.Cbor;
|
||||||
using U2F.Core.Utils;
|
using U2F.Core.Utils;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ namespace Bit.Core.Models
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// Handle newtonsoft parsing
|
// Handle newtonsoft parsing
|
||||||
Descriptor = JsonConvert.DeserializeObject<PublicKeyCredentialDescriptor>(o.Descriptor.ToString());
|
Descriptor = JsonHelpers.LegacyDeserialize<PublicKeyCredentialDescriptor>(o.Descriptor.ToString());
|
||||||
}
|
}
|
||||||
PublicKey = o.PublicKey;
|
PublicKey = o.PublicKey;
|
||||||
UserHandle = o.UserHandle;
|
UserHandle = o.UserHandle;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Billing.Models;
|
using Bit.Billing.Models;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
@ -9,8 +11,6 @@ using Bit.Core.Settings;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
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 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)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var responseJson = await response.Content.ReadAsStringAsync();
|
var receiptStatus = await response.Content.ReadFromJsonAsync<AppleReceiptStatus>();
|
||||||
var receiptStatus = JsonConvert.DeserializeObject<AppleReceiptStatus>(responseJson);
|
|
||||||
if (receiptStatus.Status == 21007)
|
if (receiptStatus.Status == 21007)
|
||||||
{
|
{
|
||||||
return await GetReceiptStatusAsync(receiptData, false, attempt + 1, receiptStatus);
|
return await GetReceiptStatusAsync(receiptData, false, attempt + 1, receiptStatus);
|
||||||
@ -124,4 +126,12 @@ namespace Bit.Core.Services
|
|||||||
return null;
|
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 Azure.Storage.Queues;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -13,7 +13,9 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
public AzureQueueEventWriteService(GlobalSettings globalSettings) : base(
|
public AzureQueueEventWriteService(GlobalSettings globalSettings) : base(
|
||||||
new QueueClient(globalSettings.Events.ConnectionString, "event"),
|
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 Azure.Storage.Queues;
|
||||||
using Bit.Core.Models.Mail;
|
using Bit.Core.Models.Mail;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -13,11 +13,11 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
public AzureQueueMailService(GlobalSettings globalSettings) : base(
|
public AzureQueueMailService(GlobalSettings globalSettings) : base(
|
||||||
new QueueClient(globalSettings.Mail.ConnectionString, "mail"),
|
new QueueClient(globalSettings.Mail.ConnectionString, "mail"),
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })
|
JsonHelpers.IgnoreWritingNull)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public Task EnqueueAsync(IMailQueueMessage message, Func<IMailQueueMessage, Task> fallback) =>
|
public Task EnqueueAsync(IMailQueueMessage message, Func<IMailQueueMessage, Task> fallback) =>
|
||||||
CreateAsync(message);
|
CreateManyAsync(new[] { message });
|
||||||
|
|
||||||
public Task EnqueueManyAsync(IEnumerable<IMailQueueMessage> messages, Func<IMailQueueMessage, Task> fallback) =>
|
public Task EnqueueManyAsync(IEnumerable<IMailQueueMessage> messages, Func<IMailQueueMessage, Task> fallback) =>
|
||||||
CreateManyAsync(messages);
|
CreateManyAsync(messages);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
@ -7,8 +8,8 @@ using Bit.Core.Entities;
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -18,11 +19,6 @@ namespace Bit.Core.Services
|
|||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
NullValueHandling = NullValueHandling.Ignore
|
|
||||||
};
|
|
||||||
|
|
||||||
public AzureQueuePushNotificationService(
|
public AzureQueuePushNotificationService(
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IHttpContextAccessor httpContextAccessor)
|
||||||
@ -170,8 +166,8 @@ namespace Bit.Core.Services
|
|||||||
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
|
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
var contextId = GetContextIdentifier(excludeCurrentContext);
|
var contextId = GetContextIdentifier(excludeCurrentContext);
|
||||||
var message = JsonConvert.SerializeObject(new PushNotificationData<T>(type, payload, contextId),
|
var message = JsonSerializer.Serialize(new PushNotificationData<T>(type, payload, contextId),
|
||||||
_jsonSettings);
|
JsonHelpers.IgnoreWritingNull);
|
||||||
await _queueClient.SendMessageAsync(message);
|
await _queueClient.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -14,10 +15,6 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
private readonly QueueClient _queueClient;
|
private readonly QueueClient _queueClient;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
NullValueHandling = NullValueHandling.Ignore,
|
|
||||||
};
|
|
||||||
|
|
||||||
public AzureQueueReferenceEventService(
|
public AzureQueueReferenceEventService(
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings)
|
||||||
@ -40,7 +37,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var message = JsonConvert.SerializeObject(referenceEvent, _jsonSerializerSettings);
|
var message = JsonSerializer.Serialize(referenceEvent, JsonHelpers.IgnoreWritingNullAndCamelCase);
|
||||||
// Messages need to be base64 encoded
|
// Messages need to be base64 encoded
|
||||||
var encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(message));
|
var encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(message));
|
||||||
await _queueClient.SendMessageAsync(encodedMessage);
|
await _queueClient.SendMessageAsync(encodedMessage);
|
||||||
|
@ -1,29 +1,22 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public abstract class AzureQueueService<T>
|
public abstract class AzureQueueService<T>
|
||||||
{
|
{
|
||||||
protected QueueClient _queueClient;
|
protected QueueClient _queueClient;
|
||||||
protected JsonSerializerSettings _jsonSettings;
|
protected JsonSerializerOptions _jsonOptions;
|
||||||
|
|
||||||
protected AzureQueueService(QueueClient queueClient, JsonSerializerSettings jsonSettings)
|
protected AzureQueueService(QueueClient queueClient, JsonSerializerOptions jsonOptions)
|
||||||
{
|
{
|
||||||
_queueClient = queueClient;
|
_queueClient = queueClient;
|
||||||
_jsonSettings = jsonSettings;
|
_jsonOptions = jsonOptions;
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CreateAsync(T message)
|
|
||||||
{
|
|
||||||
var json = JsonConvert.SerializeObject(message, _jsonSettings);
|
|
||||||
var base64 = CoreHelpers.Base64EncodeString(json);
|
|
||||||
await _queueClient.SendMessageAsync(base64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateManyAsync(IEnumerable<T> messages)
|
public async Task CreateManyAsync(IEnumerable<T> messages)
|
||||||
@ -33,19 +26,13 @@ namespace Bit.Core.Services
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!messages.Skip(1).Any())
|
foreach (var json in SerializeMany(messages, _jsonOptions))
|
||||||
{
|
|
||||||
await CreateAsync(messages.First());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var json in SerializeMany(messages, _jsonSettings))
|
|
||||||
{
|
{
|
||||||
await _queueClient.SendMessageAsync(json);
|
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
|
// Calculate Base-64 encoded text with padding
|
||||||
int getBase64Size(int byteCount) => ((4 * byteCount / 3) + 3) & ~3;
|
int getBase64Size(int byteCount) => ((4 * byteCount / 3) + 3) & ~3;
|
||||||
@ -69,7 +56,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var serializedMessages = messages.Select(message =>
|
var serializedMessages = messages.Select(message =>
|
||||||
JsonConvert.SerializeObject(message, jsonSettings));
|
JsonSerializer.Serialize(message, jsonOptions));
|
||||||
|
|
||||||
foreach (var message in serializedMessages)
|
foreach (var message in serializedMessages)
|
||||||
{
|
{
|
||||||
|
@ -3,23 +3,23 @@ using System.Collections.Generic;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Net.Http.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public abstract class BaseIdentityClientService
|
public abstract class BaseIdentityClientService : IDisposable
|
||||||
{
|
{
|
||||||
private readonly string _identityScope;
|
private readonly string _identityScope;
|
||||||
private readonly string _identityClientId;
|
private readonly string _identityClientId;
|
||||||
private readonly string _identityClientSecret;
|
private readonly string _identityClientSecret;
|
||||||
private readonly ILogger<BaseIdentityClientService> _logger;
|
private readonly ILogger<BaseIdentityClientService> _logger;
|
||||||
|
|
||||||
private dynamic _decodedToken;
|
private JsonDocument _decodedToken;
|
||||||
private DateTime? _nextAuthAttempt = null;
|
private DateTime? _nextAuthAttempt = null;
|
||||||
|
|
||||||
public BaseIdentityClientService(
|
public BaseIdentityClientService(
|
||||||
@ -127,9 +127,9 @@ namespace Bit.Core.Services
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseContent = await response.Content.ReadAsStringAsync();
|
using var jsonDocument = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
|
||||||
dynamic tokenResponse = JsonConvert.DeserializeObject(responseContent);
|
|
||||||
AccessToken = (string)tokenResponse.access_token;
|
AccessToken = jsonDocument.RootElement.GetProperty("access_token").GetString();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +145,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
if (requestObject != null)
|
if (requestObject != null)
|
||||||
{
|
{
|
||||||
var stringContent = JsonConvert.SerializeObject(requestObject);
|
Content = JsonContent.Create(requestObject);
|
||||||
Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,17 +153,16 @@ namespace Bit.Core.Services
|
|||||||
protected bool TokenNeedsRefresh(int minutes = 5)
|
protected bool TokenNeedsRefresh(int minutes = 5)
|
||||||
{
|
{
|
||||||
var decoded = DecodeToken();
|
var decoded = DecodeToken();
|
||||||
var exp = decoded?["exp"];
|
if (!decoded.RootElement.TryGetProperty("exp", out var expProp))
|
||||||
if (exp == null)
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("No exp in token.");
|
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;
|
return DateTime.UtcNow.AddMinutes(-1 * minutes) > expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JObject DecodeToken()
|
protected JsonDocument DecodeToken()
|
||||||
{
|
{
|
||||||
if (_decodedToken != null)
|
if (_decodedToken != null)
|
||||||
{
|
{
|
||||||
@ -188,8 +186,13 @@ namespace Bit.Core.Services
|
|||||||
throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts");
|
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;
|
return _decodedToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_decodedToken.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -12,7 +13,6 @@ using Bit.Core.Repositories;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -208,7 +208,7 @@ namespace Bit.Core.Services
|
|||||||
UserId = cipher.UserId,
|
UserId = cipher.UserId,
|
||||||
OrganizationId = cipher.OrganizationId,
|
OrganizationId = cipher.OrganizationId,
|
||||||
AttachmentId = attachmentId,
|
AttachmentId = attachmentId,
|
||||||
AttachmentData = JsonConvert.SerializeObject(data)
|
AttachmentData = JsonSerializer.Serialize(data)
|
||||||
});
|
});
|
||||||
cipher.AddAttachment(attachmentId, data);
|
cipher.AddAttachment(attachmentId, data);
|
||||||
await _pushService.PushSyncCipherUpdateAsync(cipher, null);
|
await _pushService.PushSyncCipherUpdateAsync(cipher, null);
|
||||||
@ -241,7 +241,7 @@ namespace Bit.Core.Services
|
|||||||
UserId = cipher.UserId,
|
UserId = cipher.UserId,
|
||||||
OrganizationId = cipher.OrganizationId,
|
OrganizationId = cipher.OrganizationId,
|
||||||
AttachmentId = attachmentId,
|
AttachmentId = attachmentId,
|
||||||
AttachmentData = JsonConvert.SerializeObject(data)
|
AttachmentData = JsonSerializer.Serialize(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
await _cipherRepository.UpdateAttachmentAsync(attachment);
|
await _cipherRepository.UpdateAttachmentAsync(attachment);
|
||||||
@ -312,7 +312,7 @@ namespace Bit.Core.Services
|
|||||||
UserId = cipher.UserId,
|
UserId = cipher.UserId,
|
||||||
OrganizationId = cipher.OrganizationId,
|
OrganizationId = cipher.OrganizationId,
|
||||||
AttachmentId = attachmentId,
|
AttachmentId = attachmentId,
|
||||||
AttachmentData = JsonConvert.SerializeObject(attachments[attachmentId])
|
AttachmentData = JsonSerializer.Serialize(attachments[attachmentId])
|
||||||
};
|
};
|
||||||
|
|
||||||
await _cipherRepository.UpdateAttachmentAsync(updatedAttachment);
|
await _cipherRepository.UpdateAttachmentAsync(updatedAttachment);
|
||||||
@ -347,7 +347,7 @@ namespace Bit.Core.Services
|
|||||||
UserId = cipher.UserId,
|
UserId = cipher.UserId,
|
||||||
OrganizationId = cipher.OrganizationId,
|
OrganizationId = cipher.OrganizationId,
|
||||||
AttachmentId = attachmentData.AttachmentId,
|
AttachmentId = attachmentData.AttachmentId,
|
||||||
AttachmentData = JsonConvert.SerializeObject(attachmentData)
|
AttachmentData = JsonSerializer.Serialize(attachmentData)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@ -8,7 +10,6 @@ using Bit.Core.Models.Business.Tokenables;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Tokens;
|
using Bit.Core.Tokens;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -77,9 +78,9 @@ namespace Bit.Core.Services
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var responseContent = await responseMessage.Content.ReadAsStringAsync();
|
using var jsonDocument = await responseMessage.Content.ReadFromJsonAsync<JsonDocument>();
|
||||||
dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent);
|
var root = jsonDocument.RootElement;
|
||||||
return (bool)jsonResponse.success;
|
return root.GetProperty("success").GetBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RequireCaptchaValidation(ICurrentContext currentContext) =>
|
public bool RequireCaptchaValidation(ICurrentContext currentContext) =>
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Entities.Provider;
|
using Bit.Core.Entities.Provider;
|
||||||
@ -565,6 +566,35 @@ namespace Bit.Core.Services
|
|||||||
var clickTrackingText = (clickTrackingOff ? "clicktracking=off" : string.Empty);
|
var clickTrackingText = (clickTrackingOff ? "clicktracking=off" : string.Empty);
|
||||||
writer.WriteSafeString($"<a href=\"{href}\" target=\"_blank\" {clickTrackingText}>{text}</a>");
|
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)
|
public async Task SendEmergencyAccessInviteEmailAsync(EmergencyAccess emergencyAccess, string name, string token)
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
@ -13,7 +14,6 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -246,7 +246,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var data = File.ReadAllText(filePath, Encoding.UTF8);
|
var data = File.ReadAllText(filePath, Encoding.UTF8);
|
||||||
return JsonConvert.DeserializeObject<UserLicense>(data);
|
return JsonSerializer.Deserialize<UserLicense>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrganizationLicense ReadOrganizationLicense(Organization organization)
|
private OrganizationLicense ReadOrganizationLicense(Organization organization)
|
||||||
@ -258,7 +258,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var data = File.ReadAllText(filePath, Encoding.UTF8);
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
@ -11,7 +12,6 @@ using Bit.Core.Repositories;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Azure.NotificationHubs;
|
using Microsoft.Azure.NotificationHubs;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -229,7 +229,7 @@ namespace Bit.Core.Services
|
|||||||
new Dictionary<string, string>
|
new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ "type", ((byte)type).ToString() },
|
{ "type", ((byte)type).ToString() },
|
||||||
{ "payload", JsonConvert.SerializeObject(payload) }
|
{ "payload", JsonSerializer.Serialize(payload) }
|
||||||
}, tag);
|
}, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using Bit.Core.Models;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -18,11 +17,6 @@ namespace Bit.Core.Services
|
|||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
NullValueHandling = NullValueHandling.Ignore
|
|
||||||
};
|
|
||||||
|
|
||||||
public NotificationsApiPushNotificationService(
|
public NotificationsApiPushNotificationService(
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
|
@ -15,7 +15,6 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Stripe;
|
using Stripe;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
@ -727,8 +726,8 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
System.IO.File.WriteAllText($"{dir}/{organization.Id}.json",
|
using var fs = System.IO.File.OpenWrite(Path.Combine(dir, $"{organization.Id}.json"));
|
||||||
JsonConvert.SerializeObject(license, Formatting.Indented));
|
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,8 +899,8 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
var dir = $"{_globalSettings.LicenseDirectory}/organization";
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
System.IO.File.WriteAllText($"{dir}/{organization.Id}.json",
|
using var fs = System.IO.File.OpenWrite(Path.Combine(dir, $"{organization.Id}.json"));
|
||||||
JsonConvert.SerializeObject(license, Formatting.Indented));
|
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||||
|
|
||||||
organization.Name = license.Name;
|
organization.Name = license.Name;
|
||||||
organization.BusinessName = license.BusinessName;
|
organization.BusinessName = license.BusinessName;
|
||||||
@ -1146,10 +1145,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
if (invite.Permissions != null)
|
if (invite.Permissions != null)
|
||||||
{
|
{
|
||||||
orgUser.Permissions = System.Text.Json.JsonSerializer.Serialize(invite.Permissions, new JsonSerializerOptions
|
orgUser.Permissions = JsonSerializer.Serialize(invite.Permissions, JsonHelpers.CamelCase);
|
||||||
{
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!orgUser.AccessAll && invite.Collections.Any())
|
if (!orgUser.AccessAll && invite.Collections.Any())
|
||||||
@ -1765,7 +1761,7 @@ namespace Bit.Core.Services
|
|||||||
// Block the user from withdrawal if auto enrollment is enabled
|
// Block the user from withdrawal if auto enrollment is enabled
|
||||||
if (resetPasswordKey == null && resetPasswordPolicy.Data != null)
|
if (resetPasswordKey == null && resetPasswordPolicy.Data != null)
|
||||||
{
|
{
|
||||||
var data = JsonConvert.DeserializeObject<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
var data = JsonSerializer.Deserialize<ResetPasswordDataModel>(resetPasswordPolicy.Data);
|
||||||
|
|
||||||
if (data?.AutoEnrollEnabled ?? false)
|
if (data?.AutoEnrollEnabled ?? false)
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Net.Http.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -76,15 +75,13 @@ namespace Bit.Core.Services
|
|||||||
request.tag = string.Concat(request.tag, "-Cat_", message.Category);
|
request.tag = string.Concat(request.tag, "-Cat_", message.Category);
|
||||||
}
|
}
|
||||||
|
|
||||||
var reqJson = JsonConvert.SerializeObject(request);
|
var responseMessage = await httpClient.PostAsJsonAsync(
|
||||||
var responseMessage = await httpClient.PostAsync(
|
|
||||||
$"https://{_globalSettings.Mail.PostalDomain}/api/v1/send/message",
|
$"https://{_globalSettings.Mail.PostalDomain}/api/v1/send/message",
|
||||||
new StringContent(reqJson, Encoding.UTF8, "application/json"));
|
request);
|
||||||
|
|
||||||
if (responseMessage.IsSuccessStatusCode)
|
if (responseMessage.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var json = await responseMessage.Content.ReadAsStringAsync();
|
var response = await responseMessage.Content.ReadFromJsonAsync<PostalResponse>();
|
||||||
var response = JsonConvert.DeserializeObject<PostalResponse>(json);
|
|
||||||
if (response.status != "success")
|
if (response.status != "success")
|
||||||
{
|
{
|
||||||
_logger.LogError("Postal send status was not successful: {0}, {1}",
|
_logger.LogError("Postal send status was not successful: {0}, {1}",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@ -12,7 +13,6 @@ using Bit.Core.Repositories;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
@ -104,8 +104,8 @@ namespace Bit.Core.Services
|
|||||||
data.Id = fileId;
|
data.Id = fileId;
|
||||||
data.Size = fileLength;
|
data.Size = fileLength;
|
||||||
data.Validated = false;
|
data.Validated = false;
|
||||||
send.Data = JsonConvert.SerializeObject(data,
|
send.Data = JsonSerializer.Serialize(data,
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
JsonHelpers.IgnoreWritingNull);
|
||||||
await SaveSendAsync(send);
|
await SaveSendAsync(send);
|
||||||
return await _sendFileStorageService.GetSendFileUploadUrlAsync(send, fileId);
|
return await _sendFileStorageService.GetSendFileUploadUrlAsync(send, fileId);
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ namespace Bit.Core.Services
|
|||||||
throw new BadRequestException("Not a File Type Send.");
|
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)
|
if (data.Validated)
|
||||||
{
|
{
|
||||||
@ -146,7 +146,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task<bool> ValidateSendFile(Send send)
|
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);
|
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.Size = realSize.Value;
|
||||||
}
|
}
|
||||||
fileData.Validated = true;
|
fileData.Validated = true;
|
||||||
send.Data = JsonConvert.SerializeObject(fileData,
|
send.Data = JsonSerializer.Serialize(fileData,
|
||||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
JsonHelpers.IgnoreWritingNull);
|
||||||
await SaveSendAsync(send);
|
await SaveSendAsync(send);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
@ -175,7 +175,7 @@ namespace Bit.Core.Services
|
|||||||
await _sendRepository.DeleteAsync(send);
|
await _sendRepository.DeleteAsync(send);
|
||||||
if (send.Type == Enums.SendType.File)
|
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 _sendFileStorageService.DeleteFileAsync(send, data.Id);
|
||||||
}
|
}
|
||||||
await _pushService.PushSyncSendDeleteAsync(send);
|
await _pushService.PushSyncSendDeleteAsync(send);
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@ -19,7 +20,6 @@ using Microsoft.AspNetCore.DataProtection;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using File = System.IO.File;
|
using File = System.IO.File;
|
||||||
using U2fLib = U2F.Core.Crypto.U2F;
|
using U2fLib = U2F.Core.Crypto.U2F;
|
||||||
|
|
||||||
@ -983,7 +983,8 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
||||||
Directory.CreateDirectory(dir);
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -1068,7 +1069,8 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
var dir = $"{_globalSettings.LicenseDirectory}/user";
|
||||||
Directory.CreateDirectory(dir);
|
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.Premium = license.Premium;
|
||||||
user.RevisionDate = DateTime.UtcNow;
|
user.RevisionDate = DateTime.UtcNow;
|
||||||
|
@ -23,7 +23,6 @@ using Bit.Core.Settings;
|
|||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Utilities
|
namespace Bit.Core.Utilities
|
||||||
{
|
{
|
||||||
@ -332,12 +331,12 @@ namespace Bit.Core.Utilities
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a clone of the given object through serializing to json and deserializing.
|
/// 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.
|
/// inaccessible setters will not be set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static T CloneObject<T>(T obj)
|
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)
|
public static bool SettingHasValue(string setting)
|
||||||
|
@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Utilities
|
namespace Bit.Core.Utilities
|
||||||
{
|
{
|
||||||
@ -41,10 +40,8 @@ namespace Bit.Core.Utilities
|
|||||||
$"Slow down! Too many requests. Try again in {rule.Period}." : _options.QuotaExceededMessage;
|
$"Slow down! Too many requests. Try again in {rule.Period}." : _options.QuotaExceededMessage;
|
||||||
httpContext.Response.Headers["Retry-After"] = retryAfter;
|
httpContext.Response.Headers["Retry-After"] = retryAfter;
|
||||||
httpContext.Response.StatusCode = _options.HttpStatusCode;
|
httpContext.Response.StatusCode = _options.HttpStatusCode;
|
||||||
|
|
||||||
httpContext.Response.ContentType = "application/json";
|
|
||||||
var errorModel = new ErrorResponseModel { Message = message };
|
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,
|
public override void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity,
|
||||||
|
@ -15,9 +15,9 @@ using System.IO;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Core.Utilities.Duo
|
namespace Bit.Core.Utilities.Duo
|
||||||
{
|
{
|
||||||
@ -175,7 +175,7 @@ namespace Bit.Core.Utilities.Duo
|
|||||||
var res = ApiCall(method, path, parameters, timeout, out var statusCode);
|
var res = ApiCall(method, path, parameters, timeout, out var statusCode);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
|
var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(res);
|
||||||
if (dict["stat"] as string == "OK")
|
if (dict["stat"] as string == "OK")
|
||||||
{
|
{
|
||||||
return dict["response"] as T;
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
@ -11,8 +12,6 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.EventsProcessor
|
namespace Bit.EventsProcessor
|
||||||
{
|
{
|
||||||
@ -109,30 +108,27 @@ namespace Bit.EventsProcessor
|
|||||||
_logger.LogInformation("Processing message.");
|
_logger.LogInformation("Processing message.");
|
||||||
var events = new List<IEvent>();
|
var events = new List<IEvent>();
|
||||||
|
|
||||||
var token = JToken.Parse(message);
|
using var jsonDocument = JsonDocument.Parse(message);
|
||||||
if (token is JArray)
|
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));
|
.SelectMany(e => EventTableEntity.IndexEvent(e));
|
||||||
events.AddRange(indexedEntities);
|
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));
|
events.AddRange(EventTableEntity.IndexEvent(eventMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _eventWriteService.CreateManyAsync(events);
|
await _eventWriteService.CreateManyAsync(events);
|
||||||
_logger.LogInformation("Processed message.");
|
_logger.LogInformation("Processed message.");
|
||||||
}
|
}
|
||||||
catch (JsonReaderException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
_logger.LogError("JsonReaderException: Unable to parse message.");
|
_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;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Infrastructure.Dapper.Repositories
|
namespace Bit.Infrastructure.Dapper.Repositories
|
||||||
{
|
{
|
||||||
@ -106,8 +105,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
public async Task CreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
public async Task CreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
||||||
{
|
{
|
||||||
cipher.SetNewId();
|
cipher.SetNewId();
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<CipherWithCollections>(
|
var objWithCollections = JsonSerializer.Deserialize<CipherWithCollections>(
|
||||||
JsonConvert.SerializeObject(cipher));
|
JsonSerializer.Serialize(cipher));
|
||||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
@ -133,8 +132,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
public async Task CreateAsync(CipherDetails cipher, IEnumerable<Guid> collectionIds)
|
public async Task CreateAsync(CipherDetails cipher, IEnumerable<Guid> collectionIds)
|
||||||
{
|
{
|
||||||
cipher.SetNewId();
|
cipher.SetNewId();
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<CipherDetailsWithCollections>(
|
var objWithCollections = JsonSerializer.Deserialize<CipherDetailsWithCollections>(
|
||||||
JsonConvert.SerializeObject(cipher));
|
JsonSerializer.Serialize(cipher));
|
||||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
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)
|
public async Task<bool> ReplaceAsync(Cipher obj, IEnumerable<Guid> collectionIds)
|
||||||
{
|
{
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<CipherWithCollections>(
|
var objWithCollections = JsonSerializer.Deserialize<CipherWithCollections>(
|
||||||
JsonConvert.SerializeObject(obj));
|
JsonSerializer.Serialize(obj));
|
||||||
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
@ -3,14 +3,13 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Infrastructure.Dapper.Repositories
|
namespace Bit.Infrastructure.Dapper.Repositories
|
||||||
{
|
{
|
||||||
@ -112,7 +111,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
public async Task CreateAsync(Collection obj, IEnumerable<SelectionReadOnly> groups)
|
public async Task CreateAsync(Collection obj, IEnumerable<SelectionReadOnly> groups)
|
||||||
{
|
{
|
||||||
obj.SetNewId();
|
obj.SetNewId();
|
||||||
var objWithGroups = JsonConvert.DeserializeObject<CollectionWithGroups>(JsonConvert.SerializeObject(obj));
|
var objWithGroups = JsonSerializer.Deserialize<CollectionWithGroups>(JsonSerializer.Serialize(obj));
|
||||||
objWithGroups.Groups = groups.ToArrayTVP();
|
objWithGroups.Groups = groups.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
@ -126,7 +125,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
|
|
||||||
public async Task ReplaceAsync(Collection obj, IEnumerable<SelectionReadOnly> groups)
|
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();
|
objWithGroups.Groups = groups.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
@ -10,7 +11,6 @@ using Bit.Core.Repositories;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Infrastructure.Dapper.Repositories
|
namespace Bit.Infrastructure.Dapper.Repositories
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
public async Task CreateAsync(Group obj, IEnumerable<SelectionReadOnly> collections)
|
public async Task CreateAsync(Group obj, IEnumerable<SelectionReadOnly> collections)
|
||||||
{
|
{
|
||||||
obj.SetNewId();
|
obj.SetNewId();
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<GroupWithCollections>(JsonConvert.SerializeObject(obj));
|
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj));
|
||||||
objWithCollections.Collections = collections.ToArrayTVP();
|
objWithCollections.Collections = collections.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
@ -109,7 +109,7 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
|
|
||||||
public async Task ReplaceAsync(Group obj, IEnumerable<SelectionReadOnly> collections)
|
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();
|
objWithCollections.Collections = collections.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
@ -11,7 +12,6 @@ using Bit.Core.Repositories;
|
|||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Infrastructure.Dapper.Repositories
|
namespace Bit.Infrastructure.Dapper.Repositories
|
||||||
{
|
{
|
||||||
@ -244,8 +244,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
public async Task<Guid> CreateAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
public async Task<Guid> CreateAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
||||||
{
|
{
|
||||||
obj.SetNewId();
|
obj.SetNewId();
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<OrganizationUserWithCollections>(
|
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
|
||||||
JsonConvert.SerializeObject(obj));
|
JsonSerializer.Serialize(obj));
|
||||||
objWithCollections.Collections = collections.ToArrayTVP();
|
objWithCollections.Collections = collections.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
@ -261,8 +261,8 @@ namespace Bit.Infrastructure.Dapper.Repositories
|
|||||||
|
|
||||||
public async Task ReplaceAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
public async Task ReplaceAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections)
|
||||||
{
|
{
|
||||||
var objWithCollections = JsonConvert.DeserializeObject<OrganizationUserWithCollections>(
|
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
|
||||||
JsonConvert.SerializeObject(obj));
|
JsonSerializer.Serialize(obj));
|
||||||
objWithCollections.Collections = collections.ToArrayTVP();
|
objWithCollections.Collections = collections.ToArrayTVP();
|
||||||
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
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 System.Threading.Tasks;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Notifications
|
namespace Bit.Notifications
|
||||||
{
|
{
|
||||||
@ -12,7 +12,7 @@ namespace Bit.Notifications
|
|||||||
public static async Task SendNotificationToHubAsync(string notificationJson,
|
public static async Task SendNotificationToHubAsync(string notificationJson,
|
||||||
IHubContext<NotificationsHub> hubContext, CancellationToken cancellationToken = default(CancellationToken))
|
IHubContext<NotificationsHub> hubContext, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var notification = JsonConvert.DeserializeObject<PushNotificationData<object>>(notificationJson);
|
var notification = JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson);
|
||||||
switch (notification.Type)
|
switch (notification.Type)
|
||||||
{
|
{
|
||||||
case PushType.SyncCipherUpdate:
|
case PushType.SyncCipherUpdate:
|
||||||
@ -20,7 +20,7 @@ namespace Bit.Notifications
|
|||||||
case PushType.SyncCipherDelete:
|
case PushType.SyncCipherDelete:
|
||||||
case PushType.SyncLoginDelete:
|
case PushType.SyncLoginDelete:
|
||||||
var cipherNotification =
|
var cipherNotification =
|
||||||
JsonConvert.DeserializeObject<PushNotificationData<SyncCipherPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncCipherPushNotification>>(
|
||||||
notificationJson);
|
notificationJson);
|
||||||
if (cipherNotification.Payload.UserId.HasValue)
|
if (cipherNotification.Payload.UserId.HasValue)
|
||||||
{
|
{
|
||||||
@ -38,7 +38,7 @@ namespace Bit.Notifications
|
|||||||
case PushType.SyncFolderCreate:
|
case PushType.SyncFolderCreate:
|
||||||
case PushType.SyncFolderDelete:
|
case PushType.SyncFolderDelete:
|
||||||
var folderNotification =
|
var folderNotification =
|
||||||
JsonConvert.DeserializeObject<PushNotificationData<SyncFolderPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
|
||||||
notificationJson);
|
notificationJson);
|
||||||
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
|
||||||
@ -49,7 +49,7 @@ namespace Bit.Notifications
|
|||||||
case PushType.SyncSettings:
|
case PushType.SyncSettings:
|
||||||
case PushType.LogOut:
|
case PushType.LogOut:
|
||||||
var userNotification =
|
var userNotification =
|
||||||
JsonConvert.DeserializeObject<PushNotificationData<UserPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
|
||||||
notificationJson);
|
notificationJson);
|
||||||
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
|
||||||
@ -58,7 +58,7 @@ namespace Bit.Notifications
|
|||||||
case PushType.SyncSendUpdate:
|
case PushType.SyncSendUpdate:
|
||||||
case PushType.SyncSendDelete:
|
case PushType.SyncSendDelete:
|
||||||
var sendNotification =
|
var sendNotification =
|
||||||
JsonConvert.DeserializeObject<PushNotificationData<SyncSendPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
|
||||||
notificationJson);
|
notificationJson);
|
||||||
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
|
||||||
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
|
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AutoFixture.Xunit2;
|
using AutoFixture.Xunit2;
|
||||||
using Bit.Api.Controllers;
|
using Bit.Api.Controllers;
|
||||||
@ -14,7 +15,6 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace Bit.Api.Test.Controllers
|
|||||||
|
|
||||||
send.Id = default;
|
send.Id = default;
|
||||||
send.Type = SendType.Text;
|
send.Type = SendType.Text;
|
||||||
send.Data = JsonConvert.SerializeObject(new Dictionary<string, string>());
|
send.Data = JsonSerializer.Serialize(new Dictionary<string, string>());
|
||||||
send.HideEmail = true;
|
send.HideEmail = true;
|
||||||
|
|
||||||
_sendService.AccessAsync(id, null).Returns((send, false, false));
|
_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;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Text.Json;
|
||||||
using Newtonsoft.Json;
|
using Bit.Core.Utilities;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Xunit.Sdk;
|
||||||
|
|
||||||
namespace Bit.Test.Common.Helpers
|
namespace Bit.Test.Common.Helpers
|
||||||
{
|
{
|
||||||
@ -29,10 +29,9 @@ namespace Bit.Test.Common.Helpers
|
|||||||
|
|
||||||
if (actualPropInfo == null)
|
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",
|
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",
|
$"Expected:\n{JsonSerializer.Serialize(expected, JsonHelpers.Indented)}\n",
|
||||||
$"Actual:\n{JsonConvert.SerializeObject(actual, new JsonSerializerSettings { Formatting = Formatting.Indented })}"));
|
$"Actual:\n{JsonSerializer.Serialize(actual, JsonHelpers.Indented)}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedPropInfo.PropertyType == typeof(string) || expectedPropInfo.PropertyType.IsValueType)
|
if (expectedPropInfo.PropertyType == typeof(string) || expectedPropInfo.PropertyType.IsValueType)
|
||||||
@ -54,5 +53,16 @@ namespace Bit.Test.Common.Helpers
|
|||||||
Assert.Equal(expected, actual);
|
Assert.Equal(expected, actual);
|
||||||
return true;
|
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,
|
protected virtual IPostprocessComposer<CipherAttachment.MetaData> ComposerAction(IFixture fixture,
|
||||||
ICustomizationComposer<CipherAttachment.MetaData> composer)
|
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)
|
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 Bit.Core.Test.AutoFixture.CipherFixtures;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Bit.Core.Test.Models
|
namespace Bit.Core.Test.Models
|
||||||
@ -12,7 +12,7 @@ namespace Bit.Core.Test.Models
|
|||||||
[InlineOrganizationCipherAutoData]
|
[InlineOrganizationCipherAutoData]
|
||||||
public void Clone_CreatesExactCopy(Cipher cipher)
|
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 System.Text.Json;
|
|
||||||
using AutoFixture.Xunit2;
|
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Serialization;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Bit.Core.Test.Models
|
namespace Bit.Core.Test.Models
|
||||||
@ -33,21 +29,30 @@ namespace Bit.Core.Test.Models
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void Serialization_Success()
|
public void Serialization_Success()
|
||||||
{
|
{
|
||||||
// minify expected json
|
var permissions = new Permissions
|
||||||
var expected = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(_exampleSerializedPermissions));
|
|
||||||
|
|
||||||
DefaultContractResolver contractResolver = new DefaultContractResolver
|
|
||||||
{
|
{
|
||||||
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(
|
// minify expected json
|
||||||
CoreHelpers.LoadClassFromJsonData<Permissions>(_exampleSerializedPermissions), new JsonSerializerSettings
|
var expected = JsonSerializer.Serialize(permissions, JsonHelpers.CamelCase);
|
||||||
{
|
|
||||||
ContractResolver = contractResolver,
|
var actual = JsonSerializer.Serialize(
|
||||||
});
|
JsonHelpers.DeserializeOrNew<Permissions>(_exampleSerializedPermissions, JsonHelpers.CamelCase),
|
||||||
|
JsonHelpers.CamelCase);
|
||||||
|
|
||||||
Console.WriteLine(actual);
|
|
||||||
Assert.Equal(expected, 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;
|
using Xunit;
|
||||||
|
|
||||||
namespace Bit.Core.Test.Models.Tables
|
namespace Bit.Core.Test.Models.Tables
|
||||||
@ -39,5 +44,43 @@ namespace Bit.Core.Test.Models.Tables
|
|||||||
|
|
||||||
Assert.Equal(expectedRemainingBytes, bytesRemaining);
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
|
using Bit.Test.Common.AutoFixture;
|
||||||
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
|
using Bit.Test.Common.Helpers;
|
||||||
using Fido2NetLib;
|
using Fido2NetLib;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@ -17,103 +24,41 @@ namespace Bit.Core.Test.Services
|
|||||||
{
|
{
|
||||||
public class UserServiceTests
|
public class UserServiceTests
|
||||||
{
|
{
|
||||||
private readonly UserService _sut;
|
[Theory, CustomAutoData(typeof(SutProviderCustomization))]
|
||||||
|
public async Task UpdateLicenseAsync_Success(SutProvider<UserService> sutProvider,
|
||||||
private readonly IUserRepository _userRepository;
|
User user, UserLicense userLicense)
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
_userRepository = Substitute.For<IUserRepository>();
|
using var tempDir = new TempDirectory();
|
||||||
_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>();
|
|
||||||
|
|
||||||
_sut = new UserService(
|
var now = DateTime.UtcNow;
|
||||||
_userRepository,
|
userLicense.Issued = now.AddDays(-10);
|
||||||
_cipherRepository,
|
userLicense.Expires = now.AddDays(10);
|
||||||
_organizationUserRepository,
|
userLicense.Version = 1;
|
||||||
_organizationRepository,
|
userLicense.Premium = true;
|
||||||
_mailService,
|
|
||||||
_pushService,
|
|
||||||
_userStore,
|
|
||||||
_optionsAccessor,
|
|
||||||
_passwordHasher,
|
|
||||||
_userValidators,
|
|
||||||
_passwordValidators,
|
|
||||||
_keyNormalizer,
|
|
||||||
_errors,
|
|
||||||
_services,
|
|
||||||
_logger,
|
|
||||||
_licenseService,
|
|
||||||
_eventService,
|
|
||||||
_applicationCacheService,
|
|
||||||
_dataProtectionProvider,
|
|
||||||
_paymentService,
|
|
||||||
_policyRepository,
|
|
||||||
_referenceEventService,
|
|
||||||
_fido2,
|
|
||||||
_currentContext,
|
|
||||||
_globalSettings,
|
|
||||||
_organizationService,
|
|
||||||
_providerUserRepository
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove this test when we add actual tests. It only proves that
|
user.EmailVerified = true;
|
||||||
// we've properly constructed the system under test.
|
user.Email = userLicense.Email;
|
||||||
[Fact]
|
|
||||||
public void ServiceExists()
|
sutProvider.GetDependency<Settings.GlobalSettings>().SelfHosted = true;
|
||||||
{
|
sutProvider.GetDependency<Settings.GlobalSettings>().LicenseDirectory = tempDir.Directory;
|
||||||
Assert.NotNull(_sut);
|
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.Data.SqlClient;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
using Bit.Migrator;
|
using Bit.Migrator;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Setup
|
namespace Bit.Setup
|
||||||
{
|
{
|
||||||
@ -273,8 +273,9 @@ namespace Bit.Setup
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resultString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
var resultString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||||
var result = JsonConvert.DeserializeObject<dynamic>(resultString);
|
using var jsonDocument = JsonSerializer.Deserialize<JsonDocument>(resultString);
|
||||||
if (!(bool)result.Enabled)
|
var root = jsonDocument.RootElement;
|
||||||
|
if (!root.GetProperty("Enabled").GetBoolean())
|
||||||
{
|
{
|
||||||
Console.WriteLine("Installation id has been disabled.");
|
Console.WriteLine("Installation id has been disabled.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Handlebars.Net" Version="1.10.1" />
|
<PackageReference Include="Handlebars.Net" Version="1.10.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
|
||||||
<PackageReference Include="YamlDotNet" Version="8.1.2" />
|
<PackageReference Include="YamlDotNet" Version="8.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user