Startup migration bug (#320)
* Startup migration bug * ModuleCreator - sql name fix * Database Manager fixes and improvements * Database Manager fixes and improvements - removed default password
This commit is contained in:
64
Oqtane.Server/Extensions/PermissionExtension.cs
Normal file
64
Oqtane.Server/Extensions/PermissionExtension.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Oqtane.Models;
|
||||||
|
|
||||||
|
namespace Oqtane.Extensions
|
||||||
|
{
|
||||||
|
public static class PermissionExtension
|
||||||
|
{
|
||||||
|
public static string EncodePermissions(this IEnumerable<Permission> permissionList)
|
||||||
|
{
|
||||||
|
List<PermissionString> permissionstrings = new List<PermissionString>();
|
||||||
|
string permissionname = "";
|
||||||
|
string permissions = "";
|
||||||
|
StringBuilder permissionsbuilder = new StringBuilder();
|
||||||
|
string securityid = "";
|
||||||
|
foreach (Permission permission in permissionList.OrderBy(item => item.PermissionName))
|
||||||
|
{
|
||||||
|
// permission collections are grouped by permissionname
|
||||||
|
if (permissionname != permission.PermissionName)
|
||||||
|
{
|
||||||
|
permissions = permissionsbuilder.ToString();
|
||||||
|
if (permissions != "")
|
||||||
|
{
|
||||||
|
permissionstrings.Add(new PermissionString { PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
|
||||||
|
}
|
||||||
|
permissionname = permission.PermissionName;
|
||||||
|
permissionsbuilder = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// deny permissions are prefixed with a "!"
|
||||||
|
string prefix = !permission.IsAuthorized ? "!" : "";
|
||||||
|
|
||||||
|
// encode permission
|
||||||
|
if (permission.UserId == null)
|
||||||
|
{
|
||||||
|
securityid = prefix + permission.Role.Name + ";";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
securityid = prefix + "[" + permission.UserId + "];";
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert deny permissions at the beginning and append grant permissions at the end
|
||||||
|
if (prefix == "!")
|
||||||
|
{
|
||||||
|
permissionsbuilder.Insert(0, securityid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permissionsbuilder.Append(securityid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions = permissionsbuilder.ToString();
|
||||||
|
if (permissions != "")
|
||||||
|
{
|
||||||
|
permissionstrings.Add(new PermissionString { PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
|
||||||
|
}
|
||||||
|
return JsonSerializer.Serialize(permissionstrings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -10,6 +12,7 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Oqtane.Controllers;
|
using Oqtane.Controllers;
|
||||||
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
@ -23,6 +26,7 @@ namespace Oqtane.Infrastructure
|
|||||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||||
private bool _isInstalled;
|
private bool _isInstalled;
|
||||||
|
|
||||||
|
|
||||||
public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory)
|
public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
@ -31,6 +35,38 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
public void StartupMigration()
|
||||||
|
{
|
||||||
|
var defaultConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey);
|
||||||
|
var defaultAlias = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
|
||||||
|
|
||||||
|
// if no values specified, fallback to IDE installer
|
||||||
|
if (string.IsNullOrEmpty(defaultConnectionString))
|
||||||
|
{
|
||||||
|
IsInstalled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var freshInstall = !IsMasterInstalled(defaultConnectionString);
|
||||||
|
var password = GetInstallationConfig(SettingKeys.HostPasswordKey, String.Empty);
|
||||||
|
var email = GetInstallationConfig(SettingKeys.HostEmailKey, String.Empty);
|
||||||
|
if (freshInstall && (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(email) || string.IsNullOrEmpty(defaultAlias)))
|
||||||
|
{
|
||||||
|
IsInstalled = false;
|
||||||
|
Message = "Incomplete startup install configuration";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = MasterMigration(defaultConnectionString, defaultAlias, null, true);
|
||||||
|
IsInstalled = result.Success;
|
||||||
|
|
||||||
|
if (_isInstalled && !IsDefaultSiteInstalled(defaultConnectionString))
|
||||||
|
{
|
||||||
|
BuildDefaultSite(password,email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool IsInstalled
|
public bool IsInstalled
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -41,10 +77,10 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
set => _isInstalled = value;
|
set => _isInstalled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckInstallState()
|
private bool CheckInstallState()
|
||||||
{
|
{
|
||||||
var defaultConnectionString = _config.GetConnectionString("DefaultConnection");
|
var defaultConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey);
|
||||||
var result = !string.IsNullOrEmpty(defaultConnectionString);
|
var result = !string.IsNullOrEmpty(defaultConnectionString);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@ -73,7 +109,6 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
Message = "Connection string is empty";
|
Message = "Connection string is empty";
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +117,6 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
connectionString = connectionString
|
connectionString = connectionString
|
||||||
.Replace("|DataDirectory|", dataDirectory);
|
.Replace("|DataDirectory|", dataDirectory);
|
||||||
//.Replace(@"\", @"\\");
|
|
||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,25 +128,23 @@ namespace Oqtane.Infrastructure
|
|||||||
var alias = installConfig.Alias;
|
var alias = installConfig.Alias;
|
||||||
var connectionString = NormalizeConnectionString(installConfig.ConnectionString, dataDirectory);
|
var connectionString = NormalizeConnectionString(installConfig.ConnectionString, dataDirectory);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(alias))
|
if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(alias))
|
||||||
{
|
{
|
||||||
result = new Installation
|
result = MasterMigration(connectionString, alias, result, installConfig.IsMaster);
|
||||||
|
if (installConfig.IsMaster && result.Success)
|
||||||
{
|
{
|
||||||
Success = false,
|
WriteVersionInfo(connectionString);
|
||||||
Message = "Connection string is empty",
|
TenantMigration(connectionString, dataDirectory);
|
||||||
};
|
UpdateConnectionStringSetting(connectionString);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MasterMigration(connectionString, alias, result, installConfig.IsMaster);
|
result = new Installation
|
||||||
if (installConfig.IsMaster && result.Success)
|
|
||||||
{
|
{
|
||||||
WriteVersionInfo(connectionString);
|
Success = false,
|
||||||
TenantMigration(connectionString, dataDirectory);
|
Message = "Connection string is empty",
|
||||||
UpdateOqtaneSettings(connectionString);
|
};
|
||||||
AddOrUpdateAppSetting("Oqtane:DefaultAlias", alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +152,7 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
if (result == null) result = new Installation {Success = false, Message = string.Empty};
|
if (result == null) result = new Installation {Success = false, Message = string.Empty};
|
||||||
|
|
||||||
|
bool firstInstall;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create empty database if does not exists
|
// create empty database if does not exists
|
||||||
@ -127,25 +160,25 @@ namespace Oqtane.Infrastructure
|
|||||||
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseSqlServer(connectionString).Options))
|
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseSqlServer(connectionString).Options))
|
||||||
{
|
{
|
||||||
dbc.Database.EnsureCreated();
|
dbc.Database.EnsureCreated();
|
||||||
|
//check for vanilla db
|
||||||
|
firstInstall = !TableExists(dbc, "SchemaVersions");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
result = new Installation
|
result.Message = e.Message;
|
||||||
{
|
|
||||||
Success = false,
|
|
||||||
Message = e.Message,
|
|
||||||
};
|
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
// when alias is not specified on first install, fallback to ide
|
||||||
|
if (firstInstall && string.IsNullOrEmpty(alias)) return result;
|
||||||
|
|
||||||
var dbUpgradeConfig = DeployChanges
|
var dbUpgradeConfig = DeployChanges
|
||||||
.To
|
.To
|
||||||
.SqlDatabase(connectionString)
|
.SqlDatabase(connectionString)
|
||||||
.WithVariable("ConnectionString", connectionString)
|
.WithVariable("ConnectionString", connectionString)
|
||||||
.WithVariable("Alias", alias)
|
.WithVariable("Alias", alias)
|
||||||
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => master || !s.Contains("Master."));
|
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => master || !s.Contains("Master."));
|
||||||
|
|
||||||
var dbUpgrade = dbUpgradeConfig.Build();
|
var dbUpgrade = dbUpgradeConfig.Build();
|
||||||
if (!dbUpgrade.IsUpgradeRequired())
|
if (!dbUpgrade.IsUpgradeRequired())
|
||||||
@ -228,13 +261,11 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateOqtaneSettings(string connectionString)
|
public static void UpdateConnectionStringSetting(string connectionString)
|
||||||
{
|
{
|
||||||
AddOrUpdateAppSetting("ConnectionStrings:DefaultConnection", connectionString);
|
AddOrUpdateAppSetting($"ConnectionStrings:{SettingKeys.ConnectionStringKey}", connectionString);
|
||||||
//AddOrUpdateAppSetting("Oqtane:DefaultAlias", connectionString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void AddOrUpdateAppSetting<T>(string sectionPathKey, T value)
|
public static void AddOrUpdateAppSetting<T>(string sectionPathKey, T value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -262,7 +293,7 @@ namespace Oqtane.Infrastructure
|
|||||||
var currentSection = remainingSections[0];
|
var currentSection = remainingSections[0];
|
||||||
if (remainingSections.Length > 1)
|
if (remainingSections.Length > 1)
|
||||||
{
|
{
|
||||||
// continue with the procress, moving down the tree
|
// continue with the process, moving down the tree
|
||||||
var nextSection = remainingSections[1];
|
var nextSection = remainingSections[1];
|
||||||
SetValueRecursively(nextSection, jsonObj[currentSection], value);
|
SetValueRecursively(nextSection, jsonObj[currentSection], value);
|
||||||
}
|
}
|
||||||
@ -273,31 +304,13 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartupMigration()
|
private void BuildDefaultSite(string password, string email)
|
||||||
{
|
|
||||||
var defaultConnectionString = _config.GetConnectionString("DefaultConnection");
|
|
||||||
var defaultAlias = _config.GetSection("Oqtane").GetValue("DefaultAlias", string.Empty);
|
|
||||||
|
|
||||||
// if no values specified, fallback to IDE installer
|
|
||||||
if (string.IsNullOrEmpty(defaultConnectionString) || string.IsNullOrEmpty(defaultAlias))
|
|
||||||
{
|
|
||||||
IsInstalled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = MasterMigration(defaultConnectionString, defaultAlias, null, true);
|
|
||||||
IsInstalled = result.Success;
|
|
||||||
if (_isInstalled)
|
|
||||||
BuildDefaultSite();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BuildDefaultSite()
|
|
||||||
{
|
{
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
//Gather required services
|
//Gather required services
|
||||||
var siteRepository = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
var siteRepository = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||||
|
|
||||||
// Build default site only if no site present
|
// Build default site only if no site present
|
||||||
if (siteRepository.GetSites().Any()) return;
|
if (siteRepository.GetSites().Any()) return;
|
||||||
|
|
||||||
@ -312,25 +325,34 @@ namespace Oqtane.Infrastructure
|
|||||||
TenantId = -1,
|
TenantId = -1,
|
||||||
Name = "Default Site",
|
Name = "Default Site",
|
||||||
LogoFileId = null,
|
LogoFileId = null,
|
||||||
DefaultThemeType = Constants.DefaultTheme,
|
DefaultThemeType = GetInstallationConfig(SettingKeys.DefaultThemeKey, Constants.DefaultTheme),
|
||||||
DefaultLayoutType = Constants.DefaultLayout,
|
DefaultLayoutType = GetInstallationConfig(SettingKeys.DefaultLayoutKey, Constants.DefaultLayout),
|
||||||
DefaultContainerType = Constants.DefaultContainer,
|
DefaultContainerType = GetInstallationConfig(SettingKeys.DefaultContainerKey, Constants.DefaultContainer),
|
||||||
|
SiteTemplateType = GetInstallationConfig(SettingKeys.SiteTemplateKey, Constants.DefaultSiteTemplate),
|
||||||
};
|
};
|
||||||
site = siteRepository.AddSite(site);
|
site = siteRepository.AddSite(site);
|
||||||
|
|
||||||
var user = new User
|
var user = new User
|
||||||
{
|
{
|
||||||
SiteId = site.SiteId,
|
SiteId = site.SiteId,
|
||||||
Username = Constants.HostUser,
|
Username = GetInstallationConfig(SettingKeys.HostUserKey, Constants.HostUser),
|
||||||
//TODO Decide default password or throw exception ??
|
Password = password,
|
||||||
Password = _config.GetSection("Oqtane").GetValue("DefaultPassword", "oQtane123"),
|
Email = email,
|
||||||
Email = _config.GetSection("Oqtane").GetValue("DefaultEmail", "nobody@cortonso.com"),
|
DisplayName = GetInstallationConfig(SettingKeys.HostUserKey, Constants.HostUser),
|
||||||
DisplayName = Constants.HostUser,
|
|
||||||
};
|
};
|
||||||
CreateHostUser(folders, userRoles, roles, users, identityUserManager, user);
|
CreateHostUser(folders, userRoles, roles, users, identityUserManager, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetInstallationConfig(string key, string defaultValue)
|
||||||
|
{
|
||||||
|
var value = _config.GetSection(SettingKeys.InstallationSection).GetValue(key, defaultValue);
|
||||||
|
// double fallback to default value - allow hold sample keys in config
|
||||||
|
if (string.IsNullOrEmpty(value)) value = defaultValue;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void CreateHostUser(IFolderRepository folderRepository, IUserRoleRepository userRoleRepository, IRoleRepository roleRepository, IUserRepository userRepository, UserManager<IdentityUser> identityUserManager, User user)
|
private static void CreateHostUser(IFolderRepository folderRepository, IUserRoleRepository userRoleRepository, IRoleRepository roleRepository, IUserRepository userRepository, UserManager<IdentityUser> identityUserManager, User user)
|
||||||
{
|
{
|
||||||
@ -356,11 +378,71 @@ namespace Oqtane.Infrastructure
|
|||||||
if (folder != null)
|
if (folder != null)
|
||||||
folderRepository.AddFolder(new Folder
|
folderRepository.AddFolder(new Folder
|
||||||
{
|
{
|
||||||
SiteId = folder.SiteId, ParentId = folder.FolderId, Name = "My Folder", Path = folder.Path + newUser.UserId + "\\", Order = 1, IsSystem = true,
|
SiteId = folder.SiteId,
|
||||||
Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"[" + newUser.UserId + "]\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"[" +
|
ParentId = folder.FolderId,
|
||||||
newUser.UserId + "]\"}]",
|
Name = "My Folder",
|
||||||
|
Path = folder.Path + newUser.UserId + "\\",
|
||||||
|
Order = 1,
|
||||||
|
IsSystem = true,
|
||||||
|
Permissions = new List<Permission>
|
||||||
|
{
|
||||||
|
new Permission(PermissionNames.Browse, newUser.UserId, true),
|
||||||
|
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
||||||
|
new Permission(PermissionNames.Edit, newUser.UserId, true),
|
||||||
|
}.EncodePermissions(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsDefaultSiteInstalled(string connectionString)
|
||||||
|
{
|
||||||
|
using (var db = new InstallationContext(connectionString))
|
||||||
|
{
|
||||||
|
return db.Tenant.Any(t => t.IsInitialized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsMasterInstalled(string connectionString)
|
||||||
|
{
|
||||||
|
using (var db = new InstallationContext(connectionString))
|
||||||
|
{
|
||||||
|
//check if DbUp was initialized
|
||||||
|
return TableExists(db, "SchemaVersions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool TableExists(DbContext context, string tableName)
|
||||||
|
{
|
||||||
|
return TableExists(context, "dbo", tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TableExists(DbContext context, string schema, string tableName)
|
||||||
|
{
|
||||||
|
var connection = context.Database.GetDbConnection();
|
||||||
|
|
||||||
|
if (connection.State.Equals(ConnectionState.Closed))
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
using (var command = connection.CreateCommand())
|
||||||
|
{
|
||||||
|
command.CommandText = @"
|
||||||
|
SELECT 1 FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = @Schema
|
||||||
|
AND TABLE_NAME = @TableName";
|
||||||
|
|
||||||
|
var schemaParam = command.CreateParameter();
|
||||||
|
schemaParam.ParameterName = "@Schema";
|
||||||
|
schemaParam.Value = schema;
|
||||||
|
command.Parameters.Add(schemaParam);
|
||||||
|
|
||||||
|
var tableNameParam = command.CreateParameter();
|
||||||
|
tableNameParam.ParameterName = "@TableName";
|
||||||
|
tableNameParam.Value = tableName;
|
||||||
|
command.Parameters.Add(tableNameParam);
|
||||||
|
|
||||||
|
return command.ExecuteScalar() != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ Create seed data
|
|||||||
SET IDENTITY_INSERT [dbo].[Tenant] ON
|
SET IDENTITY_INSERT [dbo].[Tenant] ON
|
||||||
GO
|
GO
|
||||||
INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [IsInitialized], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
|
INSERT [dbo].[Tenant] ([TenantId], [Name], [DBConnectionString], [DBSchema], [IsInitialized], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
|
||||||
VALUES (1, N'Master', N'$ConnectionString$', N'', 1, '', getdate(), '', getdate())
|
VALUES (1, N'Master', N'$ConnectionString$', N'', 0, '', getdate(), '', getdate())
|
||||||
GO
|
GO
|
||||||
SET IDENTITY_INSERT [dbo].[Tenant] OFF
|
SET IDENTITY_INSERT [dbo].[Tenant] OFF
|
||||||
GO
|
GO
|
||||||
|
@ -2,8 +2,14 @@
|
|||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": ""
|
"DefaultConnection": ""
|
||||||
},
|
},
|
||||||
"Oqtane": {
|
"Installation": {
|
||||||
"DefaultAlias": "",
|
"DefaultAlias": "",
|
||||||
"DefaultPassword": ""
|
"HostUser": "",
|
||||||
|
"HostPassword": "",
|
||||||
|
"HostEmail": "",
|
||||||
|
"SiteTemplate": "",
|
||||||
|
"DefaultTheme": "",
|
||||||
|
"DefaultLayout": "",
|
||||||
|
"DefaultContainer": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
Oqtane.Shared/Shared/SettingKeys.cs
Normal file
16
Oqtane.Shared/Shared/SettingKeys.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace Oqtane.Shared
|
||||||
|
{
|
||||||
|
public static class SettingKeys
|
||||||
|
{
|
||||||
|
public const string InstallationSection = "Installation";
|
||||||
|
public const string DefaultAliasKey = "DefaultAlias";
|
||||||
|
public const string HostUserKey = "HostUser";
|
||||||
|
public const string HostPasswordKey = "HostPassword";
|
||||||
|
public const string HostEmailKey = "HostEmail";
|
||||||
|
public const string SiteTemplateKey = "SiteTemplate";
|
||||||
|
public const string ConnectionStringKey = "DefaultConnection";
|
||||||
|
public const string DefaultThemeKey = "DefaultTheme";
|
||||||
|
public const string DefaultLayoutKey = "DefaultLayout";
|
||||||
|
public const string DefaultContainerKey = "DefaultContainer";
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user