Fix and improve valid install path checks

+ Fail if child of game folder
+ Fail if child of Program Files
+ Add test for null path
* Fix success if path null
* Check if install path exists before updating download path
This commit is contained in:
Unnoen 2021-05-20 19:54:57 +10:00
parent 367ee1a3aa
commit 9d890f2ff0
No known key found for this signature in database
GPG Key ID: 8F8E42252BA20553
3 changed files with 29 additions and 11 deletions

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
@ -22,6 +22,7 @@ using File = Alphaleonis.Win32.Filesystem.File;
using Path = Alphaleonis.Win32.Filesystem.Path;
using SectionData = Wabbajack.Common.SectionData;
using System.Collections.Generic;
using Wabbajack.Common.IO;
using Wabbajack.Lib.ModListRegistry;
using Wabbajack.VirtualFileSystem;
@ -503,14 +504,24 @@ namespace Wabbajack.Lib
await OutputFolder.Combine(directive.To).WriteAllTextAsync(data);
}
public static IErrorResponse CheckValidInstallPath(AbsolutePath path, AbsolutePath? downloadFolder)
public static IErrorResponse CheckValidInstallPath(AbsolutePath path, AbsolutePath? downloadFolder, GameMetaData? game)
{
// Check if null path
if (string.IsNullOrEmpty(path.ToString())) return ErrorResponse.Fail("Please select an install directory.");
// Check if child of game folder
if (game?.TryGetGameLocation() != null && path.IsChildOf(game.TryGetGameLocation())) return ErrorResponse.Fail("Cannot install to game directory.");
// Check if child of Program Files
if (path.IsChildOf(new AbsolutePath(KnownFolders.ProgramFiles.Path))) return ErrorResponse.Fail("Cannot install to Program Files directory.");
// If the folder doesn't exist, it's empty so we don't need to check further
if (!path.Exists) return ErrorResponse.Success;
// Check folder does not have a Wabbajack ModList
if (path.EnumerateFiles(false).Where(file => file.Exists).Any(file => file.Extension == Consts.ModListExtension))
{
return ErrorResponse.Fail($"Cannot install into a folder with a Wabbajack ModList inside of it");
return ErrorResponse.Fail($"Cannot install into a folder with a Wabbajack ModList inside of it.");
}
// Check if folder is empty

View File

@ -13,14 +13,14 @@ namespace Wabbajack.Test
public async Task CheckValidInstallPath_Empty()
{
await using var tempDir = await TempFolder.Create();
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadFolder: null).Succeeded);
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, null, null).Succeeded);
}
[Fact]
public async Task CheckValidInstallPath_DoesNotExist()
{
await using var tempDir = await TempFolder.Create();
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir.Combine("Subfolder"), downloadFolder: null).Succeeded);
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir.Combine("Subfolder"), null, null).Succeeded);
}
[Fact]
@ -29,7 +29,7 @@ namespace Wabbajack.Test
await using var tempDir = await TempFolder.Create();
await using var mo2 = await tempDir.Dir.Combine("ModOrganizer.exe").Create();
await using var molist = await tempDir.Dir.Combine(((RelativePath)"modlist")).WithExtension(Consts.ModListExtension).Create();
Assert.False(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadFolder: null).Succeeded);
Assert.False(MO2Installer.CheckValidInstallPath(tempDir.Dir, null, null).Succeeded);
}
[Fact]
@ -37,7 +37,7 @@ namespace Wabbajack.Test
{
await using var tempDir = await TempFolder.Create();
await using var tmp = await tempDir.Dir.Combine(Consts.ModOrganizer2Exe).Create();
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadFolder: null).Succeeded);
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, null, null).Succeeded);
}
[Fact]
@ -47,7 +47,7 @@ namespace Wabbajack.Test
await tempDir.Dir.DeleteDirectory();
tempDir.Dir.CreateDirectory();
await using var tmp = await tempDir.Dir.Combine($"someFile.txt").Create();
Assert.False(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadFolder: null).Succeeded);
Assert.False(MO2Installer.CheckValidInstallPath(tempDir.Dir, null, null).Succeeded);
}
[Fact]
@ -57,7 +57,14 @@ namespace Wabbajack.Test
var downloadsFolder = tempDir.Dir.Combine("downloads");
downloadsFolder.CreateDirectory();
await using var tmp = await tempDir.Dir.Combine($"downloads/someFile.txt").Create();
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadFolder: downloadsFolder).Succeeded);
Assert.True(MO2Installer.CheckValidInstallPath(tempDir.Dir, downloadsFolder, null).Succeeded);
}
[Fact]
public async Task CheckValidInstallPath_NullPath()
{
var tempDir = new AbsolutePath("", true);
Assert.True(MO2Installer.CheckValidInstallPath(tempDir, null, null).Succeeded == false);
}
#endregion
}

View File

@ -63,7 +63,7 @@ namespace Wabbajack
this.WhenAny(x => x.DownloadLocation.TargetPath),
resultSelector: (target, download) => (target, download))
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(i => MO2Installer.CheckValidInstallPath(i.target, i.download))
.Select(i => MO2Installer.CheckValidInstallPath(i.target, i.download, Parent.ModList.SourceModList.GameType.MetaData()))
.ObserveOnGuiThread();
_CanInstall = Observable.CombineLatest(
@ -83,7 +83,7 @@ namespace Wabbajack
{
if (DownloadLocation.TargetPath == default || DownloadLocation.TargetPath == installPath)
{
DownloadLocation.TargetPath = installPath.Combine("downloads");
if (installPath.Exists) DownloadLocation.TargetPath = installPath.Combine("downloads");
}
})
.DisposeWith(CompositeDisposable);