mirror of
https://github.com/bitwarden/server
synced 2025-12-15 07:43:54 +00:00
[PM-7730] Deprecate type-specific cipher properties in favor of opaque Data string (#6354)
* Marked structured fields as obsolete and add Data field to the request model * Fixed lint issues * Deprecated properties * Changed to 1mb
This commit is contained in:
@@ -7,8 +7,6 @@ using Bit.Core.Utilities;
|
|||||||
using Bit.Core.Vault.Entities;
|
using Bit.Core.Vault.Entities;
|
||||||
using Bit.Core.Vault.Enums;
|
using Bit.Core.Vault.Enums;
|
||||||
using Bit.Core.Vault.Models.Data;
|
using Bit.Core.Vault.Models.Data;
|
||||||
using NS = Newtonsoft.Json;
|
|
||||||
using NSL = Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Api.Vault.Models.Request;
|
namespace Bit.Api.Vault.Models.Request;
|
||||||
|
|
||||||
@@ -40,11 +38,26 @@ public class CipherRequestModel
|
|||||||
// TODO: Rename to Attachments whenever the above is finally removed.
|
// TODO: Rename to Attachments whenever the above is finally removed.
|
||||||
public Dictionary<string, CipherAttachmentModel> Attachments2 { get; set; }
|
public Dictionary<string, CipherAttachmentModel> Attachments2 { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherLoginModel Login { get; set; }
|
public CipherLoginModel Login { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherCardModel Card { get; set; }
|
public CipherCardModel Card { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherIdentityModel Identity { get; set; }
|
public CipherIdentityModel Identity { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherSecureNoteModel SecureNote { get; set; }
|
public CipherSecureNoteModel SecureNote { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherSSHKeyModel SSHKey { get; set; }
|
public CipherSSHKeyModel SSHKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// JSON string containing cipher-specific data
|
||||||
|
/// </summary>
|
||||||
|
[StringLength(500000)]
|
||||||
|
public string Data { get; set; }
|
||||||
public DateTime? LastKnownRevisionDate { get; set; } = null;
|
public DateTime? LastKnownRevisionDate { get; set; } = null;
|
||||||
public DateTime? ArchivedDate { get; set; }
|
public DateTime? ArchivedDate { get; set; }
|
||||||
|
|
||||||
@@ -73,23 +86,35 @@ public class CipherRequestModel
|
|||||||
|
|
||||||
public Cipher ToCipher(Cipher existingCipher)
|
public Cipher ToCipher(Cipher existingCipher)
|
||||||
{
|
{
|
||||||
|
// If Data field is provided, use it directly
|
||||||
|
if (!string.IsNullOrWhiteSpace(Data))
|
||||||
|
{
|
||||||
|
existingCipher.Data = Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback to structured fields
|
||||||
switch (existingCipher.Type)
|
switch (existingCipher.Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
var loginObj = NSL.JObject.FromObject(ToCipherLoginData(),
|
var loginData = ToCipherLoginData();
|
||||||
new NS.JsonSerializer { NullValueHandling = NS.NullValueHandling.Ignore });
|
var loginJson = JsonSerializer.Serialize(loginData, JsonHelpers.IgnoreWritingNull);
|
||||||
// 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
|
var loginObj = JsonDocument.Parse(loginJson);
|
||||||
loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove();
|
var loginDict = JsonSerializer.Deserialize<Dictionary<string, object>>(loginJson);
|
||||||
existingCipher.Data = loginObj.ToString(NS.Formatting.None);
|
loginDict?.Remove(nameof(CipherLoginData.Uri));
|
||||||
|
|
||||||
|
existingCipher.Data = JsonSerializer.Serialize(loginDict, JsonHelpers.IgnoreWritingNull);
|
||||||
break;
|
break;
|
||||||
case CipherType.Card:
|
case CipherType.Card:
|
||||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull);
|
||||||
break;
|
break;
|
||||||
case CipherType.Identity:
|
case CipherType.Identity:
|
||||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
existingCipher.Data =
|
||||||
|
JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull);
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
existingCipher.Data =
|
||||||
|
JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull);
|
||||||
break;
|
break;
|
||||||
case CipherType.SSHKey:
|
case CipherType.SSHKey:
|
||||||
existingCipher.Data = JsonSerializer.Serialize(ToCipherSSHKeyData(), JsonHelpers.IgnoreWritingNull);
|
existingCipher.Data = JsonSerializer.Serialize(ToCipherSSHKeyData(), JsonHelpers.IgnoreWritingNull);
|
||||||
@@ -97,6 +122,7 @@ public class CipherRequestModel
|
|||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
throw new ArgumentException("Unsupported type: " + nameof(Type) + ".");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
existingCipher.Reprompt = Reprompt;
|
existingCipher.Reprompt = Reprompt;
|
||||||
existingCipher.Key = Key;
|
existingCipher.Key = Key;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class CipherMiniResponseModel : ResponseModel
|
|||||||
|
|
||||||
Id = cipher.Id;
|
Id = cipher.Id;
|
||||||
Type = cipher.Type;
|
Type = cipher.Type;
|
||||||
|
Data = cipher.Data;
|
||||||
|
|
||||||
CipherData cipherData;
|
CipherData cipherData;
|
||||||
switch (cipher.Type)
|
switch (cipher.Type)
|
||||||
@@ -31,30 +32,25 @@ public class CipherMiniResponseModel : ResponseModel
|
|||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
var loginData = JsonSerializer.Deserialize<CipherLoginData>(cipher.Data);
|
var loginData = JsonSerializer.Deserialize<CipherLoginData>(cipher.Data);
|
||||||
cipherData = loginData;
|
cipherData = loginData;
|
||||||
Data = loginData;
|
|
||||||
Login = new CipherLoginModel(loginData);
|
Login = new CipherLoginModel(loginData);
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
var secureNoteData = JsonSerializer.Deserialize<CipherSecureNoteData>(cipher.Data);
|
var secureNoteData = JsonSerializer.Deserialize<CipherSecureNoteData>(cipher.Data);
|
||||||
Data = secureNoteData;
|
|
||||||
cipherData = secureNoteData;
|
cipherData = secureNoteData;
|
||||||
SecureNote = new CipherSecureNoteModel(secureNoteData);
|
SecureNote = new CipherSecureNoteModel(secureNoteData);
|
||||||
break;
|
break;
|
||||||
case CipherType.Card:
|
case CipherType.Card:
|
||||||
var cardData = JsonSerializer.Deserialize<CipherCardData>(cipher.Data);
|
var cardData = JsonSerializer.Deserialize<CipherCardData>(cipher.Data);
|
||||||
Data = cardData;
|
|
||||||
cipherData = cardData;
|
cipherData = cardData;
|
||||||
Card = new CipherCardModel(cardData);
|
Card = new CipherCardModel(cardData);
|
||||||
break;
|
break;
|
||||||
case CipherType.Identity:
|
case CipherType.Identity:
|
||||||
var identityData = JsonSerializer.Deserialize<CipherIdentityData>(cipher.Data);
|
var identityData = JsonSerializer.Deserialize<CipherIdentityData>(cipher.Data);
|
||||||
Data = identityData;
|
|
||||||
cipherData = identityData;
|
cipherData = identityData;
|
||||||
Identity = new CipherIdentityModel(identityData);
|
Identity = new CipherIdentityModel(identityData);
|
||||||
break;
|
break;
|
||||||
case CipherType.SSHKey:
|
case CipherType.SSHKey:
|
||||||
var sshKeyData = JsonSerializer.Deserialize<CipherSSHKeyData>(cipher.Data);
|
var sshKeyData = JsonSerializer.Deserialize<CipherSSHKeyData>(cipher.Data);
|
||||||
Data = sshKeyData;
|
|
||||||
cipherData = sshKeyData;
|
cipherData = sshKeyData;
|
||||||
SSHKey = new CipherSSHKeyModel(sshKeyData);
|
SSHKey = new CipherSSHKeyModel(sshKeyData);
|
||||||
break;
|
break;
|
||||||
@@ -80,15 +76,33 @@ public class CipherMiniResponseModel : ResponseModel
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid? OrganizationId { get; set; }
|
public Guid? OrganizationId { get; set; }
|
||||||
public CipherType Type { get; set; }
|
public CipherType Type { get; set; }
|
||||||
public dynamic Data { get; set; }
|
public string Data { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherLoginModel Login { get; set; }
|
public CipherLoginModel Login { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherCardModel Card { get; set; }
|
public CipherCardModel Card { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherIdentityModel Identity { get; set; }
|
public CipherIdentityModel Identity { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherSecureNoteModel SecureNote { get; set; }
|
public CipherSecureNoteModel SecureNote { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public CipherSSHKeyModel SSHKey { get; set; }
|
public CipherSSHKeyModel SSHKey { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public IEnumerable<CipherFieldModel> Fields { get; set; }
|
public IEnumerable<CipherFieldModel> Fields { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Data instead.")]
|
||||||
public IEnumerable<CipherPasswordHistoryModel> PasswordHistory { get; set; }
|
public IEnumerable<CipherPasswordHistoryModel> PasswordHistory { get; set; }
|
||||||
public IEnumerable<AttachmentResponseModel> Attachments { get; set; }
|
public IEnumerable<AttachmentResponseModel> Attachments { get; set; }
|
||||||
public bool OrganizationUseTotp { get; set; }
|
public bool OrganizationUseTotp { get; set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user