728 lines
36 KiB
C#
728 lines
36 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.Loader;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Oqtane.Databases.Interfaces;
|
|
using Oqtane.Extensions;
|
|
using Oqtane.Models;
|
|
using Oqtane.Repository;
|
|
using Oqtane.Shared;
|
|
using Oqtane.Enums;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|
// ReSharper disable ConvertToUsingDeclaration
|
|
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
|
|
// ReSharper disable UseIndexFromEndExpression
|
|
|
|
namespace Oqtane.Infrastructure
|
|
{
|
|
public class DatabaseManager : IDatabaseManager
|
|
{
|
|
private readonly IConfigManager _config;
|
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
private readonly IWebHostEnvironment _environment;
|
|
private readonly IMemoryCache _cache;
|
|
private readonly IConfigManager _configManager;
|
|
private readonly ILogger<DatabaseManager> _filelogger;
|
|
|
|
public DatabaseManager(IConfigManager config, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IMemoryCache cache, IConfigManager configManager, ILogger<DatabaseManager> filelogger)
|
|
{
|
|
_config = config;
|
|
_serviceScopeFactory = serviceScopeFactory;
|
|
_environment = environment;
|
|
_cache = cache;
|
|
_configManager = configManager;
|
|
_filelogger = filelogger;
|
|
}
|
|
|
|
public Installation IsInstalled()
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))
|
|
{
|
|
using (var db = GetInstallationContext())
|
|
{
|
|
if (db.Database.CanConnect())
|
|
{
|
|
try
|
|
{
|
|
// verify master database contains a Tenant table ( ie. validate schema is properly provisioned )
|
|
var provisioned = db.Tenant.Any();
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "Master Database Not Installed Correctly. " + ex.ToString();
|
|
}
|
|
}
|
|
else // cannot connect
|
|
{
|
|
try
|
|
{
|
|
// get the actual connection error details
|
|
db.Database.OpenConnection();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "Cannot Connect To Master Database. " + ex.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Installation Install()
|
|
{
|
|
return Install(null);
|
|
}
|
|
|
|
public Installation Install(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
ValidateConfiguration();
|
|
|
|
// get configuration
|
|
if (install == null)
|
|
{
|
|
// startup or silent installation
|
|
install = new InstallConfig
|
|
{
|
|
ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey),
|
|
TenantName = TenantNames.Master,
|
|
DatabaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey],
|
|
IsNewTenant = false
|
|
};
|
|
|
|
var installation = IsInstalled();
|
|
if (!installation.Success)
|
|
{
|
|
install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
|
|
install.HostUsername = GetInstallationConfig(SettingKeys.HostUsernameKey, UserNames.Host);
|
|
install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty);
|
|
install.HostEmail = GetInstallationConfig(SettingKeys.HostEmailKey, string.Empty);
|
|
install.HostName = GetInstallationConfig(SettingKeys.HostNameKey, UserNames.Host);
|
|
|
|
if (!string.IsNullOrEmpty(install.ConnectionString) && !string.IsNullOrEmpty(install.Aliases) && !string.IsNullOrEmpty(install.HostPassword) && !string.IsNullOrEmpty(install.HostEmail))
|
|
{
|
|
// silent install
|
|
install.SiteTemplate = GetInstallationConfig(SettingKeys.SiteTemplateKey, Constants.DefaultSiteTemplate);
|
|
install.DefaultTheme = GetInstallationConfig(SettingKeys.DefaultThemeKey, Constants.DefaultTheme);
|
|
install.DefaultContainer = GetInstallationConfig(SettingKeys.DefaultContainerKey, Constants.DefaultContainer);
|
|
install.SiteName = Constants.DefaultSite;
|
|
install.IsNewTenant = true;
|
|
}
|
|
else
|
|
{
|
|
// silent installation is missing required information
|
|
install.ConnectionString = "";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!string.IsNullOrEmpty(installation.Message))
|
|
{
|
|
// problem with prior installation
|
|
_filelogger.LogError(Utilities.LogMessage(this, installation.Message));
|
|
install.ConnectionString = "";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// install wizard or add new site
|
|
if (!string.IsNullOrEmpty(install.Aliases))
|
|
{
|
|
if (string.IsNullOrEmpty(install.SiteTemplate))
|
|
{
|
|
install.SiteTemplate = GetInstallationConfig(SettingKeys.SiteTemplateKey, Constants.DefaultSiteTemplate);
|
|
}
|
|
if (string.IsNullOrEmpty(install.DefaultTheme))
|
|
{
|
|
install.DefaultTheme = GetInstallationConfig(SettingKeys.DefaultThemeKey, Constants.DefaultTheme);
|
|
}
|
|
if (string.IsNullOrEmpty(install.DefaultContainer))
|
|
{
|
|
install.DefaultContainer = GetInstallationConfig(SettingKeys.DefaultContainerKey, Constants.DefaultContainer);
|
|
}
|
|
|
|
// add new site
|
|
if (install.TenantName != TenantNames.Master && install.ConnectionString.Contains("="))
|
|
{
|
|
_configManager.AddOrUpdateSetting($"{SettingKeys.ConnectionStringsSection}:{install.TenantName}", install.ConnectionString, false);
|
|
}
|
|
if (install.TenantName == TenantNames.Master && !install.ConnectionString.Contains("="))
|
|
{
|
|
install.ConnectionString = _config.GetConnectionString(install.ConnectionString);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Message = "Invalid Installation Configuration";
|
|
install.ConnectionString = "";
|
|
}
|
|
}
|
|
|
|
// proceed with installation/migration
|
|
if (!string.IsNullOrEmpty(install.ConnectionString))
|
|
{
|
|
result = CreateDatabase(install);
|
|
if (result.Success)
|
|
{
|
|
result = MigrateMaster(install);
|
|
if (result.Success)
|
|
{
|
|
result = CreateTenant(install);
|
|
if (result.Success)
|
|
{
|
|
result = MigrateTenants(install);
|
|
if (result.Success)
|
|
{
|
|
result = MigrateModules(install);
|
|
if (result.Success)
|
|
{
|
|
result = CreateSite(install);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation CreateDatabase(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
if (install.IsNewTenant)
|
|
{
|
|
try
|
|
{
|
|
var databaseType = install.DatabaseType;
|
|
|
|
// get database type
|
|
var type = Type.GetType(databaseType);
|
|
|
|
// create database object from type
|
|
var database = Activator.CreateInstance(type) as IDatabase;
|
|
|
|
// create data directory if does not exist
|
|
var dataDirectory = AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString();
|
|
if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory ?? String.Empty);
|
|
|
|
var dbOptions = new DbContextOptionsBuilder().UseOqtaneDatabase(database, NormalizeConnectionString(install.ConnectionString)).Options;
|
|
using (var dbc = new DbContext(dbOptions))
|
|
{
|
|
// create empty database if it does not exist
|
|
dbc.Database.EnsureCreated();
|
|
result.Success = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Creating The Database. This Is Usually Related To Your User Not Having Sufficient Rights To Perform This Operation. Please Note That You Can Also Create The Database Manually Prior To Initiating The Install Wizard. " + ex.ToString();
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation MigrateMaster(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
if (install.TenantName == TenantNames.Master)
|
|
{
|
|
using (var scope = _serviceScopeFactory.CreateScope())
|
|
{
|
|
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
|
|
|
|
var installation = IsInstalled();
|
|
try
|
|
{
|
|
UpdateConnectionString(install.ConnectionString);
|
|
UpdateDatabaseType(install.DatabaseType);
|
|
|
|
using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), null, _config))
|
|
{
|
|
AddEFMigrationsHistory(sql, install.ConnectionString, install.DatabaseType, "", true);
|
|
// push latest model into database
|
|
masterDbContext.Database.Migrate();
|
|
result.Success = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Provisioning The Master Database. This Is Usually Related To The Master Database Not Being In A Supported State. " + ex.ToString();
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation CreateTenant(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
|
|
{
|
|
using (var db = GetInstallationContext())
|
|
{
|
|
Tenant tenant;
|
|
if (install.IsNewTenant)
|
|
{
|
|
tenant = new Tenant
|
|
{
|
|
Name = install.TenantName,
|
|
DBConnectionString = (install.TenantName == TenantNames.Master) ? SettingKeys.ConnectionStringKey : install.TenantName,
|
|
DBType = install.DatabaseType,
|
|
CreatedBy = "",
|
|
CreatedOn = DateTime.UtcNow,
|
|
ModifiedBy = "",
|
|
ModifiedOn = DateTime.UtcNow
|
|
};
|
|
db.Tenant.Add(tenant);
|
|
db.SaveChanges();
|
|
_cache.Remove("tenants");
|
|
}
|
|
else
|
|
{
|
|
tenant = db.Tenant.FirstOrDefault(item => item.Name == install.TenantName);
|
|
}
|
|
|
|
var aliasNames = install.Aliases.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray();
|
|
var firstAlias = aliasNames[0];
|
|
foreach (var aliasName in aliasNames)
|
|
{
|
|
if (tenant != null)
|
|
{
|
|
var alias = new Alias
|
|
{
|
|
Name = aliasName,
|
|
TenantId = tenant.TenantId,
|
|
SiteId = -1,
|
|
IsDefault = (aliasName == firstAlias),
|
|
CreatedBy = "",
|
|
CreatedOn = DateTime.UtcNow,
|
|
ModifiedBy = "",
|
|
ModifiedOn = DateTime.UtcNow
|
|
};
|
|
db.Alias.Add(alias);
|
|
}
|
|
|
|
db.SaveChanges();
|
|
}
|
|
|
|
_cache.Remove("aliases");
|
|
}
|
|
}
|
|
|
|
result.Success = true;
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation MigrateTenants(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
var versions = Constants.ReleaseVersions.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
using (var scope = _serviceScopeFactory.CreateScope())
|
|
{
|
|
var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>();
|
|
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
|
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
|
var DBContextDependencies = scope.ServiceProvider.GetRequiredService<IDBContextDependencies>();
|
|
|
|
using (var db = GetInstallationContext())
|
|
{
|
|
foreach (var tenant in db.Tenant.ToList())
|
|
{
|
|
tenantManager.SetTenant(tenant.TenantId);
|
|
tenant.DBConnectionString = MigrateConnectionString(db, tenant);
|
|
try
|
|
{
|
|
using (var tenantDbContext = new TenantDBContext(DBContextDependencies))
|
|
{
|
|
AddEFMigrationsHistory(sql, _configManager.GetSetting($"{SettingKeys.ConnectionStringsSection}:{tenant.DBConnectionString}", ""), tenant.DBType, tenant.Version, false);
|
|
// push latest model into database
|
|
tenantDbContext.Database.Migrate();
|
|
result.Success = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Migrating The Database For Tenant " + tenant.Name + ". This Is Usually Related To Database Permissions, Connection String Mappings, Or The Database Not Being In A Supported State. " + ex.ToString();
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
|
|
// execute any version specific upgrade logic
|
|
var version = tenant.Version;
|
|
var index = Array.FindIndex(versions, item => item == version);
|
|
if (index != (versions.Length - 1))
|
|
{
|
|
try
|
|
{
|
|
for (var i = (index + 1); i < versions.Length; i++)
|
|
{
|
|
upgrades.Upgrade(tenant, versions[i]);
|
|
}
|
|
tenant.Version = versions[versions.Length - 1];
|
|
db.Entry(tenant).State = EntityState.Modified;
|
|
db.SaveChanges();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Executing Upgrade Logic On Tenant " + tenant.Name + ". " + ex.ToString();
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(result.Message))
|
|
{
|
|
result.Success = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation MigrateModules(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
using (var scope = _serviceScopeFactory.CreateScope())
|
|
{
|
|
var moduleDefinitions = scope.ServiceProvider.GetRequiredService<IModuleDefinitionRepository>();
|
|
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
|
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
|
|
|
foreach (var moduleDefinition in moduleDefinitions.GetModuleDefinitions())
|
|
{
|
|
if (!string.IsNullOrEmpty(moduleDefinition.ReleaseVersions))
|
|
{
|
|
var versions = moduleDefinition.ReleaseVersions.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
|
using (var db = GetInstallationContext())
|
|
{
|
|
if (!string.IsNullOrEmpty(moduleDefinition.ServerManagerType))
|
|
{
|
|
var moduleType = Type.GetType(moduleDefinition.ServerManagerType);
|
|
if (moduleType != null)
|
|
{
|
|
foreach (var tenant in db.Tenant.ToList())
|
|
{
|
|
var index = Array.FindIndex(versions, item => item == moduleDefinition.Version);
|
|
if (tenant.Name == install.TenantName && install.TenantName != TenantNames.Master)
|
|
{
|
|
index = -1;
|
|
}
|
|
if (index != (versions.Length - 1))
|
|
{
|
|
for (var i = (index + 1); i < versions.Length; i++)
|
|
{
|
|
try
|
|
{
|
|
if (moduleType.GetInterface("IInstallable") != null)
|
|
{
|
|
tenantManager.SetTenant(tenant.TenantId);
|
|
var moduleObject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, moduleType) as IInstallable;
|
|
if (moduleObject == null || !moduleObject.Install(tenant, versions[i]))
|
|
{
|
|
result.Message = "An Error Occurred Executing IInstallable Interface For " + moduleDefinition.ServerManagerType;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!sql.ExecuteScript(tenant, moduleType.Assembly, Utilities.GetTypeName(moduleDefinition.ModuleDefinitionName) + "." + versions[i] + ".sql"))
|
|
{
|
|
result.Message = "An Error Occurred Executing Database Script " + Utilities.GetTypeName(moduleDefinition.ModuleDefinitionName) + "." + versions[i] + ".sql";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Installing " + moduleDefinition.Name + " Version " + versions[i] + " On Tenant " + tenant.Name + " - " + ex.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(result.Message) && moduleDefinition.Version != versions[versions.Length - 1])
|
|
{
|
|
// get module definition from database to retain user customizable property values
|
|
var moduledef = db.ModuleDefinition.AsNoTracking().FirstOrDefault(item => item.ModuleDefinitionId == moduleDefinition.ModuleDefinitionId);
|
|
moduleDefinition.Name = moduledef.Name;
|
|
moduleDefinition.Description = moduledef.Description;
|
|
moduleDefinition.Categories = moduledef.Categories;
|
|
// update version
|
|
moduleDefinition.Version = versions[versions.Length - 1];
|
|
db.Entry(moduleDefinition).State = EntityState.Modified;
|
|
db.SaveChanges();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(result.Message))
|
|
{
|
|
result.Success = true;
|
|
}
|
|
else
|
|
{
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Installation CreateSite(InstallConfig install)
|
|
{
|
|
var result = new Installation { Success = false, Message = string.Empty };
|
|
|
|
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases) && !string.IsNullOrEmpty(install.SiteName))
|
|
{
|
|
try
|
|
{
|
|
using (var scope = _serviceScopeFactory.CreateScope())
|
|
{
|
|
// set the alias explicitly so the tenant can be resolved
|
|
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
|
var aliasNames = install.Aliases.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray();
|
|
var firstAlias = aliasNames[0];
|
|
var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
|
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
|
tenantManager.SetAlias(alias);
|
|
|
|
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
|
var site = sites.GetSites().FirstOrDefault(item => item.Name == install.SiteName);
|
|
if (site == null)
|
|
{
|
|
var tenants = scope.ServiceProvider.GetRequiredService<ITenantRepository>();
|
|
var users = scope.ServiceProvider.GetRequiredService<IUserRepository>();
|
|
var roles = scope.ServiceProvider.GetRequiredService<IRoleRepository>();
|
|
var userRoles = scope.ServiceProvider.GetRequiredService<IUserRoleRepository>();
|
|
var folders = scope.ServiceProvider.GetRequiredService<IFolderRepository>();
|
|
var log = scope.ServiceProvider.GetRequiredService<ILogManager>();
|
|
var identityUserManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
|
|
|
|
var tenant = tenants.GetTenants().FirstOrDefault(item => item.Name == install.TenantName);
|
|
|
|
site = new Site
|
|
{
|
|
TenantId = tenant.TenantId,
|
|
Name = install.SiteName,
|
|
LogoFileId = null,
|
|
FaviconFileId = null,
|
|
PwaIsEnabled = false,
|
|
PwaAppIconFileId = null,
|
|
PwaSplashIconFileId = null,
|
|
AllowRegistration = false,
|
|
CaptureBrokenUrls = true,
|
|
VisitorTracking = true,
|
|
DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
|
|
DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
|
|
AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
|
|
SiteTemplateType = install.SiteTemplate,
|
|
Runtime = (!string.IsNullOrEmpty(install.Runtime)) ? install.Runtime : _configManager.GetSection("Runtime").Value,
|
|
RenderMode = (!string.IsNullOrEmpty(install.RenderMode)) ? install.RenderMode : _configManager.GetSection("RenderMode").Value,
|
|
};
|
|
site = sites.AddSite(site);
|
|
|
|
if (!string.IsNullOrEmpty(install.HostUsername))
|
|
{
|
|
var identityUser = identityUserManager.FindByNameAsync(install.HostUsername).GetAwaiter().GetResult();
|
|
if (identityUser == null)
|
|
{
|
|
identityUser = new IdentityUser { UserName = install.HostUsername, Email = install.HostEmail, EmailConfirmed = true };
|
|
var create = identityUserManager.CreateAsync(identityUser, install.HostPassword).GetAwaiter().GetResult();
|
|
if (create.Succeeded)
|
|
{
|
|
var user = new User
|
|
{
|
|
SiteId = site.SiteId,
|
|
Username = install.HostUsername,
|
|
Password = install.HostPassword,
|
|
Email = install.HostEmail,
|
|
DisplayName = install.HostName,
|
|
LastIPAddress = "",
|
|
LastLoginOn = null
|
|
};
|
|
user = users.AddUser(user);
|
|
|
|
// add host role
|
|
var hostRoleId = roles.GetRoles(user.SiteId, true).FirstOrDefault(item => item.Name == RoleNames.Host)?.RoleId ?? 0;
|
|
var userRole = new UserRole { UserId = user.UserId, RoleId = hostRoleId, EffectiveDate = null, ExpiryDate = null };
|
|
userRoles.AddUserRole(userRole);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var aliasName in aliasNames)
|
|
{
|
|
alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
|
|
if (alias != null)
|
|
{
|
|
alias.SiteId = site.SiteId;
|
|
aliases.UpdateAlias(alias);
|
|
}
|
|
}
|
|
|
|
tenant.Version = Constants.Version;
|
|
tenants.UpdateTenant(tenant);
|
|
|
|
if (site != null) log.Log(site.SiteId, Shared.LogLevel.Information, this, LogFunction.Create, "Site Created {Site}", site);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Message = "An Error Occurred Creating Site. " + ex.ToString();
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(result.Message))
|
|
{
|
|
result.Success = true;
|
|
}
|
|
else
|
|
{
|
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private string DenormalizeConnectionString(string connectionString)
|
|
{
|
|
var dataDirectory = AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString();
|
|
connectionString = connectionString.Replace(dataDirectory ?? String.Empty, $"|{Constants.DataDirectory}|");
|
|
return connectionString;
|
|
}
|
|
|
|
private InstallationContext GetInstallationContext()
|
|
{
|
|
var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
|
|
var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
|
|
|
|
IDatabase database = null;
|
|
if (!string.IsNullOrEmpty(databaseType))
|
|
{
|
|
var type = Type.GetType(databaseType);
|
|
database = Activator.CreateInstance(type) as IDatabase;
|
|
}
|
|
|
|
return new InstallationContext(database, connectionString);
|
|
}
|
|
|
|
private string GetInstallationConfig(string key, string defaultValue)
|
|
{
|
|
return _configManager.GetSetting(SettingKeys.InstallationSection, key, defaultValue);
|
|
}
|
|
|
|
private string NormalizeConnectionString(string connectionString)
|
|
{
|
|
var dataDirectory = AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString();
|
|
connectionString = connectionString.Replace($"|{Constants.DataDirectory}|", dataDirectory);
|
|
return connectionString;
|
|
}
|
|
|
|
public void UpdateConnectionString(string connectionString)
|
|
{
|
|
connectionString = DenormalizeConnectionString(connectionString);
|
|
if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString)
|
|
{
|
|
_configManager.AddOrUpdateSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString, true);
|
|
}
|
|
}
|
|
|
|
public void UpdateDatabaseType(string databaseType)
|
|
{
|
|
_configManager.AddOrUpdateSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType, true);
|
|
}
|
|
|
|
public void AddEFMigrationsHistory(ISqlRepository sql, string connectionString, string databaseType, string version, bool isMaster)
|
|
{
|
|
// in version 2.1.0 the __EFMigrationsHistory tables were introduced and must be added to existing SQL Server installations
|
|
if ((isMaster || (version != null && Version.Parse(version).CompareTo(Version.Parse("2.1.0")) < 0)) && databaseType == Constants.DefaultDBType)
|
|
{
|
|
var script = (isMaster) ? "MigrateMaster.sql" : "MigrateTenant.sql";
|
|
|
|
var query = sql.GetScriptFromAssembly(Assembly.GetExecutingAssembly(), script);
|
|
query = query.Replace("{{Version}}", Constants.Version);
|
|
|
|
sql.ExecuteNonQuery(connectionString, databaseType, query);
|
|
}
|
|
}
|
|
|
|
public string MigrateConnectionString(InstallationContext db, Tenant tenant)
|
|
{
|
|
// migrate connection strings from the Tenant table to appsettings
|
|
if (tenant.DBConnectionString.Contains("="))
|
|
{
|
|
var defaultConnection = _configManager.GetConnectionString(SettingKeys.ConnectionStringKey);
|
|
if (tenant.DBConnectionString == defaultConnection)
|
|
{
|
|
tenant.DBConnectionString = SettingKeys.ConnectionStringKey;
|
|
}
|
|
else
|
|
{
|
|
_configManager.AddOrUpdateSetting($"{SettingKeys.ConnectionStringsSection}:{tenant.Name}", tenant.DBConnectionString, false);
|
|
tenant.DBConnectionString = tenant.Name;
|
|
}
|
|
db.Entry(tenant).State = EntityState.Modified;
|
|
db.SaveChanges();
|
|
}
|
|
return tenant.DBConnectionString;
|
|
}
|
|
|
|
private void ValidateConfiguration()
|
|
{
|
|
if (_configManager.GetSetting(SettingKeys.DatabaseSection, SettingKeys.DatabaseTypeKey, "") == "")
|
|
{
|
|
_configManager.AddOrUpdateSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", Constants.DefaultDBType, true);
|
|
}
|
|
if (!_configManager.GetSection(SettingKeys.AvailableDatabasesSection).Exists())
|
|
{
|
|
string databases = "[";
|
|
databases += "{ \"Name\": \"LocalDB\", \"ControlType\": \"Oqtane.Installer.Controls.LocalDBConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer\" },";
|
|
databases += "{ \"Name\": \"SQL Server\", \"ControlType\": \"Oqtane.Installer.Controls.SqlServerConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer\" },";
|
|
databases += "{ \"Name\": \"SQLite\", \"ControlType\": \"Oqtane.Installer.Controls.SqliteConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.Sqlite.SqliteDatabase, Oqtane.Database.Sqlite\" },";
|
|
databases += "{ \"Name\": \"MySQL\", \"ControlType\": \"Oqtane.Installer.Controls.MySQLConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.MySQL.SqlServerDatabase, Oqtane.Database.MySQL\" },";
|
|
databases += "{ \"Name\": \"PostgreSQL\", \"ControlType\": \"Oqtane.Installer.Controls.PostgreSQLConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.PostgreSQL.PostgreSQLDatabase, Oqtane.Database.PostgreSQL\" }";
|
|
databases += "]";
|
|
_configManager.AddOrUpdateSetting(SettingKeys.AvailableDatabasesSection, databases, true);
|
|
}
|
|
}
|
|
}
|
|
}
|