Skip to content

Commit

Permalink
Merge pull request #1045 from corbob/996-check-config-dir
Browse files Browse the repository at this point in the history
(#996) Create config directory if it doesn't exist
  • Loading branch information
gep13 authored Apr 26, 2024
2 parents 86e6f63 + 600b9f8 commit 529c961
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
15 changes: 12 additions & 3 deletions Source/ChocolateyGui.Common.Windows/Startup/ChocolateyGuiModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,22 @@ protected override void Load(ContainerBuilder builder)
var userDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.LocalAppDataPath, "data.db")};upgrade=true");

LiteDatabase globalDatabase;
var globalConfigDirectory = Path.Combine(Bootstrapper.AppDataPath, "Config");
var globalConfigDatabaseFile = Path.Combine(globalConfigDirectory, "data.db");

if (Hacks.IsElevated)
{
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true");
if (!Directory.Exists(globalConfigDirectory))
{
Directory.CreateDirectory(globalConfigDirectory);
Hacks.LockDirectory(globalConfigDirectory);
}

globalDatabase = new LiteDatabase($"filename={globalConfigDatabaseFile};upgrade=true");
}
else
{
if (!File.Exists(Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")))
if (!File.Exists(globalConfigDatabaseFile))
{
// Since the global configuration database file doesn't exist, we must be running in a state where an administrator user
// has never run Chocolatey GUI. In this case, use null, which will mean attempts to use the global database will be ignored.
Expand All @@ -163,7 +172,7 @@ protected override void Load(ContainerBuilder builder)
else
{
// Since this is a non-administrator user, they should only have read permissions to this database
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};readonly=true");
globalDatabase = new LiteDatabase($"filename={globalConfigDatabaseFile};readonly=true");
}
}

Expand Down
31 changes: 31 additions & 0 deletions Source/ChocolateyGui.Common/Hacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,43 @@
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace ChocolateyGui.Common
{
public static class Hacks
{
public static bool IsElevated => (WindowsIdentity.GetCurrent().Owner?.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid)).GetValueOrDefault(false);

// TODO: Replace this LockDirectory with calls to DotNetFileSystem's LockDirectory when https://github.com/chocolatey/ChocolateyGUI/issues/1046 is completed.
/// <summary>
/// Lock the given directory path to just Administrators being able to write. This method is copied from chocolatey.infrastructure.filesystem.DotNetFileSystem, and should be replaced with that call when the minimum Chocolatey.lib is bumped to 2.2.0 or greater.
/// </summary>
/// <param name="directoryPath">Directory path to lock down.</param>
public static void LockDirectory(string directoryPath)
{
var permissions = Directory.GetAccessControl(directoryPath);
var rules = permissions.GetAccessRules(includeExplicit: true, includeInherited: true, targetType: typeof(NTAccount));

// We first need to remove all rules
foreach (FileSystemAccessRule rule in rules)
{
permissions.RemoveAccessRuleAll(rule);
}

var bultinAdmins = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount));
var localsystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount));
var builtinUsers = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null).Translate(typeof(NTAccount));
var inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
permissions.SetAccessRule(new FileSystemAccessRule(bultinAdmins, FileSystemRights.FullControl, inheritanceFlags, PropagationFlags.None, AccessControlType.Allow));
permissions.SetAccessRule(new FileSystemAccessRule(localsystem, FileSystemRights.FullControl, inheritanceFlags, PropagationFlags.None, AccessControlType.Allow));
permissions.SetAccessRule(new FileSystemAccessRule(builtinUsers, FileSystemRights.ReadAndExecute, inheritanceFlags, PropagationFlags.None, AccessControlType.Allow));
permissions.SetOwner(bultinAdmins);
permissions.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
Directory.SetAccessControl(directoryPath, permissions);
}
}
}
15 changes: 12 additions & 3 deletions Source/ChocolateyGuiCli/Startup/ChocolateyGuiCliModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,22 @@ protected override void Load(ContainerBuilder builder)
var userDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.LocalAppDataPath, "data.db")};upgrade=true");

LiteDatabase globalDatabase;
var globalConfigDirectory = Path.Combine(Bootstrapper.AppDataPath, "Config");
var globalConfigDatabaseFile = Path.Combine(globalConfigDirectory, "data.db");

if (Hacks.IsElevated)
{
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true");
if (!Directory.Exists(globalConfigDirectory))
{
Directory.CreateDirectory(globalConfigDirectory);
Hacks.LockDirectory(globalConfigDirectory);
}

globalDatabase = new LiteDatabase($"filename={globalConfigDatabaseFile};upgrade=true");
}
else
{
if (!File.Exists(Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")))
if (!File.Exists(globalConfigDatabaseFile))
{
// Since the global configuration database file doesn't exist, we must be running in a state where an administrator user
// has never run Chocolatey GUI. In this case, use null, which will mean attempts to use the global database will be ignored.
Expand All @@ -63,7 +72,7 @@ protected override void Load(ContainerBuilder builder)
else
{
// Since this is a non-administrator user, they should only have read permissions to this database
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};readonly=true");
globalDatabase = new LiteDatabase($"filename={globalConfigDatabaseFile};readonly=true");
}
}

Expand Down

0 comments on commit 529c961

Please sign in to comment.