Added FolderWritable to DiskProvider to centralize the check.
This commit is contained in:
parent
104d35299b
commit
11803afc39
|
@ -8,7 +8,7 @@ using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Test.DiskTests
|
namespace NzbDrone.Common.Test.DiskTests
|
||||||
{
|
{
|
||||||
public class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
public abstract class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
||||||
{
|
{
|
||||||
public DirectoryInfo GetFilledTempFolder()
|
public DirectoryInfo GetFilledTempFolder()
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,38 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
Subject.FolderExists(@"C:\ThisBetterNotExist\".AsOsAgnostic()).Should().BeFalse();
|
Subject.FolderExists(@"C:\ThisBetterNotExist\".AsOsAgnostic()).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void SetWritePermissions(string path, bool writable);
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void FolderWritable_should_return_true_for_writable_directory()
|
||||||
|
{
|
||||||
|
var tempFolder = GetTempFilePath();
|
||||||
|
Directory.CreateDirectory(tempFolder);
|
||||||
|
|
||||||
|
var result = Subject.FolderWritable(tempFolder);
|
||||||
|
|
||||||
|
result.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void FolderWritable_should_return_false_for_unwritable_directory()
|
||||||
|
{
|
||||||
|
var tempFolder = GetTempFilePath();
|
||||||
|
Directory.CreateDirectory(tempFolder);
|
||||||
|
|
||||||
|
SetWritePermissions(tempFolder, false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = Subject.FolderWritable(tempFolder);
|
||||||
|
|
||||||
|
result.Should().BeFalse();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SetWritePermissions(tempFolder, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MoveFile_should_overwrite_existing_file()
|
public void MoveFile_should_overwrite_existing_file()
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,25 @@ namespace NzbDrone.Common.Disk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool FolderWritable(string path)
|
||||||
|
{
|
||||||
|
Ensure.That(path, () => path).IsValidPath();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var testPath = Path.Combine(path, "sonarr_write_test.txt");
|
||||||
|
var testContent = string.Format("This file was created to verify if '{0}' is writable. It should've been automatically deleted. Feel free to delete it.", path);
|
||||||
|
File.WriteAllText(testPath, testContent);
|
||||||
|
File.Delete(testPath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Trace("Directory '{0}' isn't writable. {1}", path, e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string[] GetDirectories(string path)
|
public string[] GetDirectories(string path)
|
||||||
{
|
{
|
||||||
Ensure.That(path, () => path).IsValidPath();
|
Ensure.That(path, () => path).IsValidPath();
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace NzbDrone.Common.Disk
|
||||||
bool FolderExists(string path);
|
bool FolderExists(string path);
|
||||||
bool FileExists(string path);
|
bool FileExists(string path);
|
||||||
bool FileExists(string path, StringComparison stringComparison);
|
bool FileExists(string path, StringComparison stringComparison);
|
||||||
|
bool FolderWritable(string path);
|
||||||
string[] GetDirectories(string path);
|
string[] GetDirectories(string path);
|
||||||
string[] GetFiles(string path, SearchOption searchOption);
|
string[] GetFiles(string path, SearchOption searchOption);
|
||||||
long GetFolderSize(string path);
|
long GetFolderSize(string path);
|
||||||
|
|
|
@ -122,30 +122,8 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
|
|
||||||
protected override void Test(List<ValidationFailure> failures)
|
protected override void Test(List<ValidationFailure> failures)
|
||||||
{
|
{
|
||||||
failures.AddIfNotNull(TestWrite(Settings.NzbFolder, "NzbFolder"));
|
failures.AddIfNotNull(TestFolder(Settings.NzbFolder, "NzbFolder"));
|
||||||
failures.AddIfNotNull(TestWrite(Settings.StrmFolder, "StrmFolder"));
|
failures.AddIfNotNull(TestFolder(Settings.StrmFolder, "StrmFolder"));
|
||||||
}
|
|
||||||
|
|
||||||
private ValidationFailure TestWrite(String folder, String propertyName)
|
|
||||||
{
|
|
||||||
if (!_diskProvider.FolderExists(folder))
|
|
||||||
{
|
|
||||||
return new ValidationFailure(propertyName, "Folder does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var testPath = Path.Combine(folder, "drone_test.txt");
|
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
|
||||||
_diskProvider.DeleteFile(testPath);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException(ex.Message, ex);
|
|
||||||
return new ValidationFailure(propertyName, "Unable to write to folder");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String WriteStrmFile(String title, String nzbFile)
|
private String WriteStrmFile(String title, String nzbFile)
|
||||||
|
|
|
@ -104,15 +104,9 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
if (mustBeWritable)
|
if (mustBeWritable)
|
||||||
{
|
{
|
||||||
try
|
if (!_diskProvider.FolderWritable(folder))
|
||||||
{
|
{
|
||||||
var testPath = Path.Combine(folder, "drone_test.txt");
|
_logger.Error("Folder '{0}' is not writable.", folder);
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
|
||||||
_diskProvider.DeleteFile(testPath);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException(ex.Message, ex);
|
|
||||||
return new NzbDroneValidationFailure(propertyName, "Unable to write to folder")
|
return new NzbDroneValidationFailure(propertyName, "Unable to write to folder")
|
||||||
{
|
{
|
||||||
DetailedDescription = "The folder you specified is not writable. Please verify the folder permissions for the user account that is used to execute NzbDrone."
|
DetailedDescription = "The folder you specified is not writable. Please verify the folder permissions for the user account that is used to execute NzbDrone."
|
||||||
|
|
|
@ -31,13 +31,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "Drone factory folder does not exist");
|
return new HealthCheck(GetType(), HealthCheckResult.Error, "Drone factory folder does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
if (!_diskProvider.FolderWritable(droneFactoryFolder))
|
||||||
{
|
|
||||||
var testPath = Path.Combine(droneFactoryFolder, "drone_test.txt");
|
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
|
||||||
_diskProvider.DeleteFile(testPath);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
{
|
||||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to write to drone factory folder");
|
return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to write to drone factory folder");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||||
{
|
{
|
||||||
if (OsInfo.IsWindows || _configFileProvider.UpdateAutomatically)
|
if (OsInfo.IsWindows || _configFileProvider.UpdateAutomatically)
|
||||||
{
|
{
|
||||||
try
|
if (!_diskProvider.FolderWritable(_appFolderInfo.StartUpFolder))
|
||||||
{
|
|
||||||
var testPath = Path.Combine(_appFolderInfo.StartUpFolder, "drone_test.txt");
|
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
|
||||||
_diskProvider.DeleteFile(testPath);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
{
|
||||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to update, running from write-protected folder");
|
return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to update, running from write-protected folder");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using NUnit.Framework;
|
using Mono.Unix;
|
||||||
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Test.DiskTests;
|
using NzbDrone.Common.Test.DiskTests;
|
||||||
|
|
||||||
namespace NzbDrone.Mono.Test.DiskProviderTests
|
namespace NzbDrone.Mono.Test.DiskProviderTests
|
||||||
|
@ -11,5 +12,21 @@ namespace NzbDrone.Mono.Test.DiskProviderTests
|
||||||
{
|
{
|
||||||
MonoOnly();
|
MonoOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SetWritePermissions(string path, bool writable)
|
||||||
|
{
|
||||||
|
// Remove Write permissions, we're still owner so we can clean it up, but we'll have to do that explicitly.
|
||||||
|
|
||||||
|
var entry = UnixFileSystemInfo.GetFileSystemEntry(path);
|
||||||
|
|
||||||
|
if (writable)
|
||||||
|
{
|
||||||
|
entry.FileAccessPermissions |= FileAccessPermissions.UserWrite | FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.FileAccessPermissions &= ~(FileAccessPermissions.UserWrite | FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,10 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\Libraries\Mono.Posix.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
using NUnit.Framework;
|
using System.IO;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Test.DiskTests;
|
using NzbDrone.Common.Test.DiskTests;
|
||||||
|
|
||||||
namespace NzbDrone.Windows.Test.DiskProviderTests
|
namespace NzbDrone.Windows.Test.DiskProviderTests
|
||||||
|
@ -11,5 +14,26 @@ namespace NzbDrone.Windows.Test.DiskProviderTests
|
||||||
{
|
{
|
||||||
WindowsOnly();
|
WindowsOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SetWritePermissions(string path, bool writable)
|
||||||
|
{
|
||||||
|
// Remove Write permissions, we're owner and have Delete permissions, so we can still clean it up.
|
||||||
|
|
||||||
|
var owner = WindowsIdentity.GetCurrent().Owner;
|
||||||
|
var accessControlType = writable ? AccessControlType.Allow : AccessControlType.Deny;
|
||||||
|
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
{
|
||||||
|
var ds = Directory.GetAccessControl(path);
|
||||||
|
ds.SetAccessRule(new FileSystemAccessRule(owner, FileSystemRights.Write, accessControlType));
|
||||||
|
Directory.SetAccessControl(path, ds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fs = File.GetAccessControl(path);
|
||||||
|
fs.SetAccessRule(new FileSystemAccessRule(owner, FileSystemRights.Write, accessControlType));
|
||||||
|
File.SetAccessControl(path, fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue