using System.Text.Json; using System.Text.Json.Serialization; using Bit.Infrastructure.EntityFramework.Models; using Microsoft.EntityFrameworkCore; namespace Bit.Infrastructure.EntityFramework.Repositories { public class DatabaseContext : DbContext { public const string postgresIndetermanisticCollation = "postgresIndetermanisticCollation"; public DatabaseContext(DbContextOptions options) : base(options) { } public DbSet Ciphers { get; set; } public DbSet Collections { get; set; } public DbSet CollectionCiphers { get; set; } public DbSet CollectionGroups { get; set; } public DbSet CollectionUsers { get; set; } public DbSet Devices { get; set; } public DbSet EmergencyAccesses { get; set; } public DbSet Events { get; set; } public DbSet Folders { get; set; } public DbSet Grants { get; set; } public DbSet Groups { get; set; } public DbSet GroupUsers { get; set; } public DbSet Installations { get; set; } public DbSet Organizations { get; set; } public DbSet OrganizationApiKeys { get; set; } public DbSet OrganizationSponsorships { get; set; } public DbSet OrganizationConnections { get; set; } public DbSet OrganizationUsers { get; set; } public DbSet Policies { get; set; } public DbSet Providers { get; set; } public DbSet ProviderUsers { get; set; } public DbSet ProviderOrganizations { get; set; } public DbSet Sends { get; set; } public DbSet SsoConfigs { get; set; } public DbSet SsoUsers { get; set; } public DbSet TaxRates { get; set; } public DbSet Transactions { get; set; } public DbSet Users { get; set; } protected override void OnModelCreating(ModelBuilder builder) { var eCipher = builder.Entity(); var eCollection = builder.Entity(); var eCollectionCipher = builder.Entity(); var eCollectionUser = builder.Entity(); var eCollectionGroup = builder.Entity(); var eDevice = builder.Entity(); var eEmergencyAccess = builder.Entity(); var eEvent = builder.Entity(); var eFolder = builder.Entity(); var eGrant = builder.Entity(); var eGroup = builder.Entity(); var eGroupUser = builder.Entity(); var eInstallation = builder.Entity(); var eOrganization = builder.Entity(); var eOrganizationSponsorship = builder.Entity(); var eOrganizationUser = builder.Entity(); var ePolicy = builder.Entity(); var eProvider = builder.Entity(); var eProviderUser = builder.Entity(); var eProviderOrganization = builder.Entity(); var eSend = builder.Entity(); var eSsoConfig = builder.Entity(); var eSsoUser = builder.Entity(); var eTaxRate = builder.Entity(); var eTransaction = builder.Entity(); var eUser = builder.Entity(); var eOrganizationApiKey = builder.Entity(); var eOrganizationConnection = builder.Entity(); eCipher.Property(c => c.Id).ValueGeneratedNever(); eCollection.Property(c => c.Id).ValueGeneratedNever(); eEmergencyAccess.Property(c => c.Id).ValueGeneratedNever(); eEvent.Property(c => c.Id).ValueGeneratedNever(); eFolder.Property(c => c.Id).ValueGeneratedNever(); eGroup.Property(c => c.Id).ValueGeneratedNever(); eInstallation.Property(c => c.Id).ValueGeneratedNever(); eOrganization.Property(c => c.Id).ValueGeneratedNever(); eOrganizationSponsorship.Property(c => c.Id).ValueGeneratedNever(); eOrganizationUser.Property(c => c.Id).ValueGeneratedNever(); ePolicy.Property(c => c.Id).ValueGeneratedNever(); eProvider.Property(c => c.Id).ValueGeneratedNever(); eProviderUser.Property(c => c.Id).ValueGeneratedNever(); eProviderOrganization.Property(c => c.Id).ValueGeneratedNever(); eSend.Property(c => c.Id).ValueGeneratedNever(); eTransaction.Property(c => c.Id).ValueGeneratedNever(); eUser.Property(c => c.Id).ValueGeneratedNever(); eOrganizationApiKey.Property(c => c.Id).ValueGeneratedNever(); eOrganizationConnection.Property(c => c.Id).ValueGeneratedNever(); eCollectionCipher.HasKey(cc => new { cc.CollectionId, cc.CipherId }); eCollectionUser.HasKey(cu => new { cu.CollectionId, cu.OrganizationUserId }); eCollectionGroup.HasKey(cg => new { cg.CollectionId, cg.GroupId }); eGrant.HasKey(x => x.Key); eGroupUser.HasKey(gu => new { gu.GroupId, gu.OrganizationUserId }); if (Database.IsNpgsql()) { // the postgres provider doesn't currently support database level non-deterministic collations. // see https://www.npgsql.org/efcore/misc/collations-and-case-sensitivity.html#database-collation builder.HasCollation(postgresIndetermanisticCollation, locale: "en-u-ks-primary", provider: "icu", deterministic: false); eUser.Property(e => e.Email).UseCollation(postgresIndetermanisticCollation); eSsoUser.Property(e => e.ExternalId).UseCollation(postgresIndetermanisticCollation); eOrganization.Property(e => e.Identifier).UseCollation(postgresIndetermanisticCollation); // } eCipher.ToTable(nameof(Cipher)); eCollection.ToTable(nameof(Collection)); eCollectionCipher.ToTable(nameof(CollectionCipher)); eDevice.ToTable(nameof(Device)); eEmergencyAccess.ToTable(nameof(EmergencyAccess)); eEvent.ToTable(nameof(Event)); eFolder.ToTable(nameof(Folder)); eGrant.ToTable(nameof(Grant)); eGroup.ToTable(nameof(Group)); eGroupUser.ToTable(nameof(GroupUser)); eInstallation.ToTable(nameof(Installation)); eOrganization.ToTable(nameof(Organization)); eOrganizationSponsorship.ToTable(nameof(OrganizationSponsorship)); eOrganizationUser.ToTable(nameof(OrganizationUser)); ePolicy.ToTable(nameof(Policy)); eProvider.ToTable(nameof(Provider)); eProviderUser.ToTable(nameof(ProviderUser)); eProviderOrganization.ToTable(nameof(ProviderOrganization)); eSend.ToTable(nameof(Send)); eSsoConfig.ToTable(nameof(SsoConfig)); eSsoUser.ToTable(nameof(SsoUser)); eTaxRate.ToTable(nameof(TaxRate)); eTransaction.ToTable(nameof(Transaction)); eUser.ToTable(nameof(User)); eOrganizationApiKey.ToTable(nameof(OrganizationApiKey)); eOrganizationConnection.ToTable(nameof(OrganizationConnection)); } } }