Complete legacy operator UI and playout migration
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Runtime.Versioning;
|
||||
using MBN_STOCK_WEBVIEW.Infrastructure;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.Infrastructure.Tests;
|
||||
|
||||
public sealed class TrustedManualDirectoryTests
|
||||
{
|
||||
[Fact]
|
||||
public void Prepare_creates_nested_private_directory_with_protected_acl()
|
||||
{
|
||||
using var parent = new TemporaryDirectory();
|
||||
var target = Path.Combine(parent.Path, "operator", "private");
|
||||
|
||||
var prepared = TrustedManualDirectory.PreparePrivateWritableDirectory(target);
|
||||
|
||||
Assert.Equal(Path.GetFullPath(target), prepared);
|
||||
Assert.True(Directory.Exists(prepared));
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
AssertPrivateAcl(prepared);
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static void AssertPrivateAcl(string directory)
|
||||
{
|
||||
var security = new DirectoryInfo(directory).GetAccessControl(
|
||||
AccessControlSections.Access);
|
||||
Assert.True(security.AreAccessRulesProtected);
|
||||
Assert.DoesNotContain(
|
||||
security.GetAccessRules(true, true, typeof(SecurityIdentifier))
|
||||
.Cast<FileSystemAccessRule>(),
|
||||
rule => rule.IsInherited);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Writable_store_rejects_acl_expanded_to_world_readable()
|
||||
{
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var directory = new TemporaryDirectory();
|
||||
TrustedManualDirectory.PreparePrivateWritableDirectory(directory.Path);
|
||||
var info = new DirectoryInfo(directory.Path);
|
||||
var security = info.GetAccessControl();
|
||||
security.AddAccessRule(new FileSystemAccessRule(
|
||||
new SecurityIdentifier(WellKnownSidType.WorldSid, null),
|
||||
FileSystemRights.Read,
|
||||
AccessControlType.Allow));
|
||||
info.SetAccessControl(security);
|
||||
|
||||
Assert.Throws<S5025TrustedManualDataException>(() =>
|
||||
new S5025TrustedManualFileStore(directory.Path));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Writable_lease_pins_directory_against_rename_race()
|
||||
{
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var parent = new TemporaryDirectory();
|
||||
var directory = Path.Combine(parent.Path, "operator");
|
||||
TrustedManualDirectory.PreparePrivateWritableDirectory(directory);
|
||||
using (var store = new S5025TrustedManualFileStore(directory))
|
||||
{
|
||||
Assert.ThrowsAny<IOException>(() =>
|
||||
Directory.Move(directory, Path.Combine(parent.Path, "redirected")));
|
||||
}
|
||||
|
||||
Directory.Move(directory, Path.Combine(parent.Path, "released"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Prepare_rejects_reparse_ancestor_before_creating_target()
|
||||
{
|
||||
using var parent = new TemporaryDirectory();
|
||||
using var outside = new TemporaryDirectory();
|
||||
var link = Path.Combine(parent.Path, "linked");
|
||||
try
|
||||
{
|
||||
Directory.CreateSymbolicLink(link, outside.Path);
|
||||
}
|
||||
catch (Exception exception) when (exception is
|
||||
UnauthorizedAccessException or IOException or PlatformNotSupportedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Throws<S5025TrustedManualDataException>(() =>
|
||||
TrustedManualDirectory.PreparePrivateWritableDirectory(
|
||||
Path.Combine(link, "must-not-be-created")));
|
||||
Assert.False(Directory.Exists(Path.Combine(outside.Path, "must-not-be-created")));
|
||||
}
|
||||
|
||||
private sealed class TemporaryDirectory : IDisposable
|
||||
{
|
||||
public TemporaryDirectory()
|
||||
{
|
||||
Path = System.IO.Path.Combine(
|
||||
System.IO.Path.GetTempPath(),
|
||||
Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(Path);
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(Path, recursive: true);
|
||||
}
|
||||
catch (Exception exception) when (exception is
|
||||
IOException or UnauthorizedAccessException)
|
||||
{
|
||||
// Cleanup must not hide the test result.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user