Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Install Wizard will only be displayed if the Master database connection string in appsettings.json is not specified. This addresses a potential security issue where the Install Wizard could be displayed in an existing installation if the Master database connection failed during startup. #1205

Merged
merged 2 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions Oqtane.Client/App.razor
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
@inject IInstallationService InstallationService
@inject IInstallationService InstallationService

@if (_initialized)
{
@if (!_installed)
@if (!_installation.Success)
{
<Installer />
}
else
{
<CascadingAuthenticationState>
<CascadingValue Value="@PageState">
<SiteRouter OnStateChange="@ChangeState" />
</CascadingValue>
</CascadingAuthenticationState>
@if (string.IsNullOrEmpty(_installation.Message))
{
<CascadingAuthenticationState>
<CascadingValue Value="@PageState">
<SiteRouter OnStateChange="@ChangeState" />
</CascadingValue>
</CascadingAuthenticationState>
}
else
{
<div class="app-alert">
@_installation.Message
</div>
}
}
}

@code {
private Installation _installation;
private bool _initialized;
private bool _installed;

private PageState PageState { get; set; }

protected override async Task OnParametersSetAsync()
{
var installation = await InstallationService.IsInstalled();
_installed = installation.Success;
_installation = await InstallationService.IsInstalled();
_initialized = true;
}

Expand Down
2 changes: 1 addition & 1 deletion Oqtane.Client/Modules/Admin/Sites/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ else
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" ResourceKey="EditSite" /></td>
<td><ActionDialog Header="Delete Site" Message="@Localizer["Are You Sure You Wish To Delete The {0} Site?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" ResourceKey="DeleteSite" /></td>
<td><a href="@(_scheme + context.Name)">@context.Name</a></td>
<td><a href="@(_scheme + context.Name +"?reload")">@context.Name</a></td>
</Row>
</Pager>
}
Expand Down
3 changes: 1 addition & 2 deletions Oqtane.Server/Controllers/InstallationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public Installation Post([FromBody] InstallConfig config)
[HttpGet("installed")]
public Installation IsInstalled()
{
bool isInstalled = _databaseManager.IsInstalled();
return new Installation {Success = isInstalled, Message = string.Empty};
return _databaseManager.IsInstalled();
}

[HttpGet("upgrade")]
Expand Down
30 changes: 21 additions & 9 deletions Oqtane.Server/Infrastructure/DatabaseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,30 @@ public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceSc
_cache = cache;
}

public bool IsInstalled()
public Installation IsInstalled()
{
var defaultConnectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
var result = !string.IsNullOrEmpty(defaultConnectionString);
if (result)
var result = new Installation { Success = false, Message = string.Empty };
if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))
{
result.Success = true;
using (var scope = _serviceScopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<MasterDBContext>();
result = db.Database.CanConnect();
if (result)
if (db.Database.CanConnect())
{
try
{
result = db.Tenant.Any();
var provisioned = db.Tenant.Any();
}
catch
{
result = false;
result.Message = "Master Database Not Installed Correctly";
}
}
else
{
result.Message = "Cannot Connect To Master Database";
}
}
}
return result;
Expand All @@ -74,7 +77,8 @@ public Installation Install(InstallConfig install)
// startup or silent installation
install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false };

if (!IsInstalled())
var installation = IsInstalled();
if (!installation.Success)
{
install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty);
Expand All @@ -97,6 +101,14 @@ public Installation Install(InstallConfig install)
install.ConnectionString = "";
}
}
else
{
if (!string.IsNullOrEmpty(installation.Message))
{
// problem with prior installation
install.ConnectionString = "";
}
}
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Oqtane.Models;
using Oqtane.Models;
using Oqtane.Shared;

namespace Oqtane.Infrastructure
{
public interface IDatabaseManager
{
bool IsInstalled();
Installation IsInstalled();
Installation Install();
Installation Install(InstallConfig install);
}
Expand Down
15 changes: 9 additions & 6 deletions Oqtane.Server/Infrastructure/UpgradeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScop

public void Upgrade(Tenant tenant, string version)
{
// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute logic once
var pageTemplates = new List<PageTemplate>();

// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute the logic once
switch (version)
{
case "0.9.0":
// add a page to all existing sites on upgrade

// this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade
var pageTemplates = new List<PageTemplate>();
//pageTemplates.Add(new PageTemplate
//{
// Name = "Test",
Expand Down Expand Up @@ -68,7 +66,12 @@ public void Upgrade(Tenant tenant, string version)
case "2.0.2":
if (tenant.Name == TenantNames.Master)
{
Directory.Delete(Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()), true);
// remove Internal module template files as they are no longer supported
var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString());
if (Directory.Exists(internalTemplatePath))
{
Directory.Delete(internalTemplatePath, true);
}
}
break;
}
Expand Down
4 changes: 3 additions & 1 deletion Oqtane.Server/Pages/_Host.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@

@if (Model.Message != "")
{
@Model.Message
<div class="app-alert">
@Model.Message
</div>
}

<script src="js/interop.js"></script>
Expand Down
9 changes: 8 additions & 1 deletion Oqtane.Server/wwwroot/css/app.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');

html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
Expand Down Expand Up @@ -125,6 +125,13 @@ app {
vertical-align: inherit;
}

.app-alert {
padding: 20px;
background-color: #f44336; /* red */
color: white;
margin-bottom: 15px;
}

/* Tooltips */
.app-tooltip {
cursor: help;
Expand Down