using System; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Oqtane.Databases.Interfaces; using Oqtane.Extensions; using Oqtane.Infrastructure; using Oqtane.Migrations.Framework; using Oqtane.Models; using Oqtane.Repository.Databases.Interfaces; using Oqtane.Shared; // ReSharper disable CheckNamespace // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global namespace Oqtane.Repository { public class TenantDBContext : IdentityUserContext, IMultiDatabase { private readonly ITenantManager _tenantManager; private readonly IHttpContextAccessor _accessor; private readonly IConfigurationRoot _config; private string _connectionString = ""; private string _databaseType = ""; public TenantDBContext(DbContextOptions options, IDBContextDependencies DBContextDependencies) : base(options) { _tenantManager = DBContextDependencies.TenantManager; _accessor = DBContextDependencies.Accessor; _config = DBContextDependencies.Config; } public IDatabase ActiveDatabase { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.ReplaceService(); // specify the SchemaVersion for .NET Identity as it is not being persisted when using AddIdentityCore() var services = new ServiceCollection(); services.AddIdentityCore(options => { options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; }); optionsBuilder.UseApplicationServiceProvider(services.BuildServiceProvider()); if (string.IsNullOrEmpty(_connectionString)) { Tenant tenant = _tenantManager.GetTenant(); if (tenant != null) { _connectionString = _config.GetConnectionString(tenant.DBConnectionString); if (_connectionString != null) { _connectionString = _connectionString.Replace($"|{Constants.DataDirectory}|", AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString()); _databaseType = tenant.DBType; } else { // tenant connection string does not exist in appsettings.json } } } if (!string.IsNullOrEmpty(_databaseType)) { var type = Type.GetType(_databaseType); ActiveDatabase = Activator.CreateInstance(type) as IDatabase; } if (!string.IsNullOrEmpty(_connectionString) && ActiveDatabase != null) { optionsBuilder.UseOqtaneDatabase(ActiveDatabase, _connectionString); } base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); ActiveDatabase.UpdateIdentityStoreTableNames(builder); } public override int SaveChanges() { DbContextUtils.SaveChanges(this, _accessor); return base.SaveChanges(); } public override Task SaveChangesAsync(CancellationToken cancellationToken = default) { DbContextUtils.SaveChanges(this, _accessor); return base.SaveChangesAsync(cancellationToken); } public virtual DbSet Site { get; set; } public virtual DbSet Page { get; set; } public virtual DbSet PageModule { get; set; } public virtual DbSet Module { get; set; } public virtual DbSet User { get; set; } public virtual DbSet Profile { get; set; } public virtual DbSet Role { get; set; } public virtual DbSet UserRole { get; set; } public virtual DbSet Permission { get; set; } public virtual DbSet Setting { get; set; } public virtual DbSet Log { get; set; } public virtual DbSet Notification { get; set; } public virtual DbSet Folder { get; set; } public virtual DbSet File { get; set; } public virtual DbSet Language { get; set; } public virtual DbSet Visitor { get; set; } public virtual DbSet UrlMapping { get; set; } public virtual DbSet SearchContent { get; set; } public virtual DbSet SearchContentProperty { get; set; } public virtual DbSet SearchContentWord { get; set; } public virtual DbSet SearchWord { get; set; } public virtual DbSet MigrationHistory { get; set; } } }