1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-06 21:48:12 -05:00

[PM-2944] Make Entities Nullable On Unowned Types (#4388)

* Enable `nullable` For Collection

* Enable `nullable` For `CollectionCipher`

* Enable `nullable` For `CollectionGroup`

* Enable `nullable` For `CollectionUser`

* Enable `nullable` For `Device`

* Enable `nullable` For `Event`

* Enable `nullable` For `Folder`

* Enable `nullable` For `Installation`

* Enable `nullable` For `IRevisable`

* Enable `nullable` For `IStorable`

* Enable `nullable` For `IStorableSubscriber`

* Enable `nullable` For `ITableObject`

* Enable `nullable` For `OrganizationApiKey`

* Enable `nullable` For `OrganizationConnection`

* Enable `nullable` For `OrganizationDomain`

* Enable `nullable` For `OrganizationSponsorship`

* Enable `nullable` For `Role`

* Enable `nullable` For `TaxRate`

* Enable `nullable` For `Transaction`

* Enable `nullable` For `User`
This commit is contained in:
Justin Baur 2024-07-03 15:17:02 -04:00 committed by GitHub
parent 0d3a7b3dd5
commit 6eb2a6e75d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 99 additions and 52 deletions

View File

@ -1,15 +1,17 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class Collection : ITableObject<Guid> public class Collection : ITableObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }
public string Name { get; set; } public string Name { get; set; } = null!;
[MaxLength(300)] [MaxLength(300)]
public string ExternalId { get; set; } public string? ExternalId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow; public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow; public DateTime RevisionDate { get; set; } = DateTime.UtcNow;

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public class CollectionCipher public class CollectionCipher
{ {
public Guid CollectionId { get; set; } public Guid CollectionId { get; set; }

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public class CollectionGroup public class CollectionGroup
{ {
public Guid CollectionId { get; set; } public Guid CollectionId { get; set; }

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public class CollectionUser public class CollectionUser
{ {
public Guid CollectionId { get; set; } public Guid CollectionId { get; set; }

View File

@ -1,6 +1,8 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class Device : ITableObject<Guid> public class Device : ITableObject<Guid>
@ -8,12 +10,12 @@ public class Device : ITableObject<Guid>
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid UserId { get; set; } public Guid UserId { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string Name { get; set; } public string Name { get; set; } = null!;
public Enums.DeviceType Type { get; set; } public Enums.DeviceType Type { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string Identifier { get; set; } public string Identifier { get; set; } = null!;
[MaxLength(255)] [MaxLength(255)]
public string PushToken { get; set; } public string? PushToken { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
@ -21,20 +23,20 @@ public class Device : ITableObject<Guid>
/// Intended to be the users symmetric key that is encrypted in some form, the current way to encrypt this is with /// Intended to be the users symmetric key that is encrypted in some form, the current way to encrypt this is with
/// the devices public key. /// the devices public key.
/// </summary> /// </summary>
public string EncryptedUserKey { get; set; } public string? EncryptedUserKey { get; set; }
/// <summary> /// <summary>
/// Intended to be the public key that was generated for a device upon trust and encrypted. Currenly encrypted using /// Intended to be the public key that was generated for a device upon trust and encrypted. Currenly encrypted using
/// a users symmetric key so that when trusted and unlocked a user can decrypt the public key for all their devices. /// a users symmetric key so that when trusted and unlocked a user can decrypt the public key for all their devices.
/// This enabled a user to rotate the keys for all of their devices. /// This enabled a user to rotate the keys for all of their devices.
/// </summary> /// </summary>
public string EncryptedPublicKey { get; set; } public string? EncryptedPublicKey { get; set; }
/// <summary> /// <summary>
/// Intended to be the private key that was generated for a device upon trust and encrypted. Currenly encrypted with /// Intended to be the private key that was generated for a device upon trust and encrypted. Currenly encrypted with
/// the devices key, that upon successful login a user can decrypt this value and therefor decrypt their vault. /// the devices key, that upon successful login a user can decrypt this value and therefor decrypt their vault.
/// </summary> /// </summary>
public string EncryptedPrivateKey { get; set; } public string? EncryptedPrivateKey { get; set; }
public void SetNewId() public void SetNewId()

View File

@ -3,6 +3,8 @@ using Bit.Core.Enums;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class Event : ITableObject<Guid>, IEvent public class Event : ITableObject<Guid>, IEvent
@ -49,10 +51,10 @@ public class Event : ITableObject<Guid>, IEvent
public Guid? ProviderOrganizationId { get; set; } public Guid? ProviderOrganizationId { get; set; }
public DeviceType? DeviceType { get; set; } public DeviceType? DeviceType { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string IpAddress { get; set; } public string? IpAddress { get; set; }
public Guid? ActingUserId { get; set; } public Guid? ActingUserId { get; set; }
public EventSystemUser? SystemUser { get; set; } public EventSystemUser? SystemUser { get; set; }
public string DomainName { get; set; } public string? DomainName { get; set; }
public Guid? SecretId { get; set; } public Guid? SecretId { get; set; }
public Guid? ServiceAccountId { get; set; } public Guid? ServiceAccountId { get; set; }

View File

@ -1,13 +1,15 @@
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Vault.Entities; namespace Bit.Core.Vault.Entities;
public class Folder : ITableObject<Guid> public class Folder : ITableObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid UserId { get; set; } public Guid UserId { get; set; }
public string Name { get; set; } public string? Name { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public interface IRevisable public interface IRevisable
{ {
DateTime CreationDate { get; } DateTime CreationDate { get; }

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public interface IStorable public interface IStorable
{ {
long? Storage { get; set; } long? Storage { get; set; }

View File

@ -1,4 +1,6 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public interface IStorableSubscriber : IStorable, ISubscriber public interface IStorableSubscriber : IStorable, ISubscriber
{ } { }

View File

@ -1,5 +1,7 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
public interface ITableObject<T> where T : IEquatable<T> public interface ITableObject<T> where T : IEquatable<T>
{ {
T Id { get; set; } T Id { get; set; }

View File

@ -1,15 +1,17 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class Installation : ITableObject<Guid> public class Installation : ITableObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
[MaxLength(256)] [MaxLength(256)]
public string Email { get; set; } public string Email { get; set; } = null!;
[MaxLength(150)] [MaxLength(150)]
public string Key { get; set; } public string Key { get; set; } = null!;
public bool Enabled { get; set; } public bool Enabled { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;

View File

@ -2,6 +2,8 @@
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class OrganizationApiKey : ITableObject<Guid> public class OrganizationApiKey : ITableObject<Guid>
@ -10,7 +12,7 @@ public class OrganizationApiKey : ITableObject<Guid>
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }
public OrganizationApiKeyType Type { get; set; } public OrganizationApiKeyType Type { get; set; }
[MaxLength(30)] [MaxLength(30)]
public string ApiKey { get; set; } public string ApiKey { get; set; } = null!;
public DateTime RevisionDate { get; set; } public DateTime RevisionDate { get; set; }
public void SetNewId() public void SetNewId()

View File

@ -1,13 +1,17 @@
using System.Text.Json; using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.OrganizationConnectionConfigs; using Bit.Core.Models.OrganizationConnectionConfigs;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class OrganizationConnection<T> : OrganizationConnection where T : IConnectionConfig public class OrganizationConnection<T> : OrganizationConnection where T : IConnectionConfig
{ {
public new T Config [DisallowNull]
public new T? Config
{ {
get => base.GetConfig<T>(); get => base.GetConfig<T>();
set => base.SetConfig(value); set => base.SetConfig(value);
@ -20,17 +24,22 @@ public class OrganizationConnection : ITableObject<Guid>
public OrganizationConnectionType Type { get; set; } public OrganizationConnectionType Type { get; set; }
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }
public bool Enabled { get; set; } public bool Enabled { get; set; }
public string Config { get; set; } public string? Config { get; set; }
public void SetNewId() public void SetNewId()
{ {
Id = CoreHelpers.GenerateComb(); Id = CoreHelpers.GenerateComb();
} }
public T GetConfig<T>() where T : IConnectionConfig public T? GetConfig<T>() where T : IConnectionConfig
{ {
try try
{ {
if (Config is null)
{
return default;
}
return JsonSerializer.Deserialize<T>(Config); return JsonSerializer.Deserialize<T>(Config);
} }
catch (JsonException) catch (JsonException)

View File

@ -1,15 +1,17 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class OrganizationDomain : ITableObject<Guid> public class OrganizationDomain : ITableObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }
public string Txt { get; set; } public string Txt { get; set; } = null!;
[MaxLength(255)] [MaxLength(255)]
public string DomainName { get; set; } public string DomainName { get; set; } = null!;
public DateTime CreationDate { get; set; } = DateTime.UtcNow; public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime? VerifiedDate { get; private set; } public DateTime? VerifiedDate { get; private set; }
public DateTime NextRunDate { get; private set; } public DateTime NextRunDate { get; private set; }

View File

@ -2,6 +2,8 @@
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class OrganizationSponsorship : ITableObject<Guid> public class OrganizationSponsorship : ITableObject<Guid>
@ -11,9 +13,9 @@ public class OrganizationSponsorship : ITableObject<Guid>
public Guid SponsoringOrganizationUserId { get; set; } public Guid SponsoringOrganizationUserId { get; set; }
public Guid? SponsoredOrganizationId { get; set; } public Guid? SponsoredOrganizationId { get; set; }
[MaxLength(256)] [MaxLength(256)]
public string FriendlyName { get; set; } public string? FriendlyName { get; set; }
[MaxLength(256)] [MaxLength(256)]
public string OfferedToEmail { get; set; } public string? OfferedToEmail { get; set; }
public PlanSponsorshipType? PlanSponsorshipType { get; set; } public PlanSponsorshipType? PlanSponsorshipType { get; set; }
public DateTime? LastSyncDate { get; set; } public DateTime? LastSyncDate { get; set; }
public DateTime? ValidUntil { get; set; } public DateTime? ValidUntil { get; set; }

View File

@ -1,9 +1,11 @@
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
#nullable enable
/// <summary> /// <summary>
/// This class is not used. It is implemented to make the Identity provider happy. /// This class is not used. It is implemented to make the Identity provider happy.
/// </summary> /// </summary>
public class Role public class Role
{ {
public string Name { get; set; } public string Name { get; set; } = null!;
} }

View File

@ -1,17 +1,19 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class TaxRate : ITableObject<string> public class TaxRate : ITableObject<string>
{ {
[MaxLength(40)] [MaxLength(40)]
public string Id { get; set; } public string Id { get; set; } = null!;
[MaxLength(50)] [MaxLength(50)]
public string Country { get; set; } public string Country { get; set; } = null!;
[MaxLength(2)] [MaxLength(2)]
public string State { get; set; } public string? State { get; set; }
[MaxLength(10)] [MaxLength(10)]
public string PostalCode { get; set; } public string PostalCode { get; set; } = null!;
public decimal Rate { get; set; } public decimal Rate { get; set; }
public bool Active { get; set; } public bool Active { get; set; }

View File

@ -2,6 +2,8 @@
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class Transaction : ITableObject<Guid> public class Transaction : ITableObject<Guid>
@ -14,11 +16,11 @@ public class Transaction : ITableObject<Guid>
public bool? Refunded { get; set; } public bool? Refunded { get; set; }
public decimal? RefundedAmount { get; set; } public decimal? RefundedAmount { get; set; }
[MaxLength(100)] [MaxLength(100)]
public string Details { get; set; } public string? Details { get; set; }
public PaymentMethodType? PaymentMethodType { get; set; } public PaymentMethodType? PaymentMethodType { get; set; }
public GatewayType? Gateway { get; set; } public GatewayType? Gateway { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string GatewayId { get; set; } public string? GatewayId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow; public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public Guid? ProviderId { get; set; } public Guid? ProviderId { get; set; }

View File

@ -7,37 +7,39 @@ using Bit.Core.Tools.Entities;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
#nullable enable
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser, IReferenceable public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser, IReferenceable
{ {
private Dictionary<TwoFactorProviderType, TwoFactorProvider> _twoFactorProviders; private Dictionary<TwoFactorProviderType, TwoFactorProvider>? _twoFactorProviders;
public Guid Id { get; set; } public Guid Id { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string Name { get; set; } public string? Name { get; set; }
[Required] [Required]
[MaxLength(256)] [MaxLength(256)]
public string Email { get; set; } public string Email { get; set; } = null!;
public bool EmailVerified { get; set; } public bool EmailVerified { get; set; }
[MaxLength(300)] [MaxLength(300)]
public string MasterPassword { get; set; } public string? MasterPassword { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string MasterPasswordHint { get; set; } public string? MasterPasswordHint { get; set; }
[MaxLength(10)] [MaxLength(10)]
public string Culture { get; set; } = "en-US"; public string Culture { get; set; } = "en-US";
[Required] [Required]
[MaxLength(50)] [MaxLength(50)]
public string SecurityStamp { get; set; } public string SecurityStamp { get; set; } = null!;
public string TwoFactorProviders { get; set; } public string? TwoFactorProviders { get; set; }
[MaxLength(32)] [MaxLength(32)]
public string TwoFactorRecoveryCode { get; set; } public string? TwoFactorRecoveryCode { get; set; }
public string EquivalentDomains { get; set; } public string? EquivalentDomains { get; set; }
public string ExcludedGlobalEquivalentDomains { get; set; } public string? ExcludedGlobalEquivalentDomains { get; set; }
public DateTime AccountRevisionDate { get; set; } = DateTime.UtcNow; public DateTime AccountRevisionDate { get; set; } = DateTime.UtcNow;
public string Key { get; set; } public string? Key { get; set; }
public string PublicKey { get; set; } public string? PublicKey { get; set; }
public string PrivateKey { get; set; } public string? PrivateKey { get; set; }
public bool Premium { get; set; } public bool Premium { get; set; }
public DateTime? PremiumExpirationDate { get; set; } public DateTime? PremiumExpirationDate { get; set; }
public DateTime? RenewalReminderDate { get; set; } public DateTime? RenewalReminderDate { get; set; }
@ -45,15 +47,15 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
public short? MaxStorageGb { get; set; } public short? MaxStorageGb { get; set; }
public GatewayType? Gateway { get; set; } public GatewayType? Gateway { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string GatewayCustomerId { get; set; } public string? GatewayCustomerId { get; set; }
[MaxLength(50)] [MaxLength(50)]
public string GatewaySubscriptionId { get; set; } public string? GatewaySubscriptionId { get; set; }
public string ReferenceData { get; set; } public string? ReferenceData { get; set; }
[MaxLength(100)] [MaxLength(100)]
public string LicenseKey { get; set; } public string? LicenseKey { get; set; }
[Required] [Required]
[MaxLength(30)] [MaxLength(30)]
public string ApiKey { get; set; } public string ApiKey { get; set; } = null!;
public KdfType Kdf { get; set; } = KdfType.PBKDF2_SHA256; public KdfType Kdf { get; set; } = KdfType.PBKDF2_SHA256;
public int KdfIterations { get; set; } = AuthConstants.PBKDF2_ITERATIONS.Default; public int KdfIterations { get; set; } = AuthConstants.PBKDF2_ITERATIONS.Default;
public int? KdfMemory { get; set; } public int? KdfMemory { get; set; }
@ -65,7 +67,7 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
public int FailedLoginCount { get; set; } public int FailedLoginCount { get; set; }
public DateTime? LastFailedLoginDate { get; set; } public DateTime? LastFailedLoginDate { get; set; }
[MaxLength(7)] [MaxLength(7)]
public string AvatarColor { get; set; } public string? AvatarColor { get; set; }
public DateTime? LastPasswordChangeDate { get; set; } public DateTime? LastPasswordChangeDate { get; set; }
public DateTime? LastKdfChangeDate { get; set; } public DateTime? LastKdfChangeDate { get; set; }
public DateTime? LastKeyRotationDate { get; set; } public DateTime? LastKeyRotationDate { get; set; }
@ -76,12 +78,12 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
Id = CoreHelpers.GenerateComb(); Id = CoreHelpers.GenerateComb();
} }
public string BillingEmailAddress() public string? BillingEmailAddress()
{ {
return Email?.ToLowerInvariant()?.Trim(); return Email?.ToLowerInvariant()?.Trim();
} }
public string BillingName() public string? BillingName()
{ {
return Name; return Name;
} }
@ -125,7 +127,7 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
public bool IsExpired() => PremiumExpirationDate.HasValue && PremiumExpirationDate.Value <= DateTime.UtcNow; public bool IsExpired() => PremiumExpirationDate.HasValue && PremiumExpirationDate.Value <= DateTime.UtcNow;
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders() public Dictionary<TwoFactorProviderType, TwoFactorProvider>? GetTwoFactorProviders()
{ {
if (string.IsNullOrWhiteSpace(TwoFactorProviders)) if (string.IsNullOrWhiteSpace(TwoFactorProviders))
{ {
@ -178,7 +180,7 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>()); SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>());
} }
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider) public TwoFactorProvider? GetTwoFactorProvider(TwoFactorProviderType provider)
{ {
var providers = GetTwoFactorProviders(); var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider)) if (providers == null || !providers.ContainsKey(provider))