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

refactor: extract ACL related functionality #913

Merged
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4e51bc6
Fix incorrect value for `rollForward` in global.json
vbreuss Nov 15, 2022
9907d0b
Restrict to "LatestMinor"
vbreuss Nov 15, 2022
9355797
Only update version
vbreuss Nov 15, 2022
fae87ee
Re-Implement FileSystemExtensibility
vbreuss Nov 15, 2022
bc83607
Remove ACL-Features from Interfaces
vbreuss Nov 15, 2022
27f4e62
Replace implementation with ACL extension methods
vbreuss Nov 15, 2022
d160c5d
Adjust implementation in TestingHelpers
vbreuss Nov 15, 2022
33089c8
Adjust Parity-Tests
vbreuss Nov 15, 2022
7fd4e89
Enable Serialization
vbreuss Nov 15, 2022
67058b5
Throw correct exception when file or directory was not found
vbreuss Nov 15, 2022
ccc766a
Adjust tests
vbreuss Nov 15, 2022
af1ecbd
Revert not-working changes to global.json
vbreuss Nov 15, 2022
94a82c2
Cleanup
vbreuss Nov 15, 2022
43042ef
Fix lazy initialization of AccessControl
vbreuss Nov 15, 2022
f02b929
Update src/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs
vbreuss Nov 16, 2022
e96ea48
Update src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs
vbreuss Nov 16, 2022
5c580b1
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Nov 16, 2022
a5194e1
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Nov 17, 2022
e4ce495
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Nov 18, 2022
bd5f6bf
Fix Codacy-Issues
vbreuss Nov 20, 2022
e967bc4
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Nov 20, 2022
76e320b
Rename "Clone" to "CloneFrom"
vbreuss Nov 21, 2022
fe9efba
Implement review findings:
vbtig Nov 23, 2022
83b5817
Cleanup changed code
vbtig Nov 23, 2022
84290ce
Implement review findings from @siprbaum
vbtig Nov 25, 2022
3e5ca88
Merge remote-tracking branch 'origin/main' into topic/extract-acl-rel…
vbtig Nov 28, 2022
cb8cf44
Fix merge error
vbtig Nov 28, 2022
a522144
Implement review comments
vbtig Dec 2, 2022
b8e701c
Bump major version to 19.0
vbtig Dec 2, 2022
66d5386
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Dec 2, 2022
73243c9
Merge branch 'main' into topic/extract-acl-related-functionality
vbreuss Dec 8, 2022
cbaf4cc
refactor: delete extra file
fgreinacher Dec 8, 2022
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
fgreinacher marked this conversation as resolved.
Show resolved Hide resolved

namespace System.IO.Abstractions.TestingHelpers
{
internal class FileSystemExtensibility
{
private readonly Dictionary<string, object> _metadata = new();

public virtual void StoreMetadata(string key, object value)
{
_metadata[key] = value;
}

public virtual object RetrieveMetadata(string key)
{
if (_metadata.TryGetValue(key, out object value))
{
return value;
}

return default;
}

internal void CloneFrom(FileSystemExtensibility template)
vbreuss marked this conversation as resolved.
Show resolved Hide resolved
{
foreach (var item in template._metadata)
{
_metadata[item.Key] = item.Value;
}
}
}
}
60 changes: 2 additions & 58 deletions src/System.IO.Abstractions.TestingHelpers/MockDirectory.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Runtime.Versioning;
using System.Security.AccessControl;
using System.Text.RegularExpressions;

namespace System.IO.Abstractions.TestingHelpers
Expand Down Expand Up @@ -39,17 +36,10 @@ public class MockDirectory : DirectoryBase
/// <inheritdoc />
public override IDirectoryInfo CreateDirectory(string path)
{
return CreateDirectoryInternal(path, null);
return CreateDirectoryInternal(path);
}


/// <inheritdoc />
public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity)
{
return CreateDirectoryInternal(path, directorySecurity);
}

private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity directorySecurity)
private IDirectoryInfo CreateDirectoryInternal(string path)
{
if (path == null)
{
Expand Down Expand Up @@ -80,11 +70,6 @@ private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity di

var created = new MockDirectoryInfo(mockFileDataAccessor, path);

if (directorySecurity != null)
{
created.SetAccessControl(directorySecurity);
}

return created;
}

Expand Down Expand Up @@ -173,31 +158,6 @@ public override bool Exists(string path)
}


/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override DirectorySecurity GetAccessControl(string path)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
path = path.TrimSlashes();

if (!mockFileDataAccessor.Directory.Exists(path))
{
throw CommonExceptions.CouldNotFindPartOfPath(path);
}

var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path);
return directoryData.AccessControl;
}


/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections)
{
return GetAccessControl(path);
}


/// <inheritdoc />
public override DateTime GetCreationTime(string path)
{
Expand Down Expand Up @@ -559,22 +519,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi

#endif

/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override void SetAccessControl(string path, DirectorySecurity directorySecurity)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
path = path.TrimSlashes();

if (!mockFileDataAccessor.Directory.Exists(path))
{
throw CommonExceptions.CouldNotFindPartOfPath(path);
}

var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path);
directoryData.AccessControl = directorySecurity;
}

/// <inheritdoc />
public override void SetCreationTime(string path, DateTime creationTime)
{
Expand Down
15 changes: 9 additions & 6 deletions src/System.IO.Abstractions.TestingHelpers/MockDirectoryData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ namespace System.IO.Abstractions.TestingHelpers
[Serializable]
public class MockDirectoryData : MockFileData
{

[NonSerialized]
private DirectorySecurity accessControl;

/// <inheritdoc />
public MockDirectoryData() : base(string.Empty)
{
Expand All @@ -25,9 +21,16 @@ public new DirectorySecurity AccessControl
{
// DirectorySecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way.
// This let's us use this class as long as we don't use AccessControl property.
return accessControl ?? (accessControl = new DirectorySecurity());
var value = Extensibility.RetrieveMetadata("AccessControl:DirectorySecurity");
if (value is not DirectorySecurity directorySecurity)
{
directorySecurity = new DirectorySecurity();
Extensibility.StoreMetadata("AccessControl:DirectorySecurity", directorySecurity);
}

return directorySecurity;
vbreuss marked this conversation as resolved.
Show resolved Hide resolved
}
set { accessControl = value; }
set { Extensibility.StoreMetadata("AccessControl:DirectorySecurity", value); }
}
}
}
70 changes: 41 additions & 29 deletions src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Versioning;
using System.Security.AccessControl;

namespace System.IO.Abstractions.TestingHelpers
Expand All @@ -8,7 +9,7 @@ namespace System.IO.Abstractions.TestingHelpers

/// <inheritdoc />
[Serializable]
public class MockDirectoryInfo : DirectoryInfoBase
public class MockDirectoryInfo : DirectoryInfoBase, IFileSystemAclSupport
{
private readonly IMockFileDataAccessor mockFileDataAccessor;
private readonly string directoryPath;
Expand All @@ -26,6 +27,15 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire
{
this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor));

if (directoryPath== null)
vbreuss marked this conversation as resolved.
Show resolved Hide resolved
{
throw new ArgumentNullException("path", StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL"));
}
if (directoryPath.Trim() == string.Empty)
{
throw CommonExceptions.PathIsNotOfALegalForm("path");
}

originalPath = directoryPath;
directoryPath = mockFileDataAccessor.Path.GetFullPath(directoryPath);

Expand Down Expand Up @@ -179,14 +189,7 @@ public override void Create()
mockFileDataAccessor.Directory.CreateDirectory(FullName);
refreshOnNextRead = true;
}

/// <inheritdoc />
public override void Create(DirectorySecurity directorySecurity)
{
mockFileDataAccessor.Directory.CreateDirectory(FullName, directorySecurity);
refreshOnNextRead = true;
}


/// <inheritdoc />
public override IDirectoryInfo CreateSubdirectory(string path)
{
Expand Down Expand Up @@ -277,19 +280,7 @@ public override IEnumerable<IFileSystemInfo> EnumerateFileSystemInfos(string sea
return GetFileSystemInfos(searchPattern, enumerationOptions);
}
#endif

/// <inheritdoc />
public override DirectorySecurity GetAccessControl()
{
return mockFileDataAccessor.Directory.GetAccessControl(directoryPath);
}

/// <inheritdoc />
public override DirectorySecurity GetAccessControl(AccessControlSections includeSections)
{
return mockFileDataAccessor.Directory.GetAccessControl(directoryPath, includeSections);
}


/// <inheritdoc />
public override IDirectoryInfo[] GetDirectories()
{
Expand Down Expand Up @@ -388,13 +379,7 @@ public override void MoveTo(string destDirName)
{
mockFileDataAccessor.Directory.Move(directoryPath, destDirName);
}

/// <inheritdoc />
public override void SetAccessControl(DirectorySecurity directorySecurity)
{
mockFileDataAccessor.Directory.SetAccessControl(directoryPath, directorySecurity);
}


/// <inheritdoc />
public override IDirectoryInfo Parent
{
Expand Down Expand Up @@ -435,5 +420,32 @@ public override string ToString()
{
return originalPath;
}

/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl()" />
[SupportedOSPlatform("windows")]
public object GetAccessControl()
{
return GetMockDirectoryData().AccessControl;
}

/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl(IFileSystemAclSupport.AccessControlSections)" />
[SupportedOSPlatform("windows")]
public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections)
{
return GetMockDirectoryData().AccessControl;
}

/// <inheritdoc cref="IFileSystemAclSupport.SetAccessControl(object)" />
[SupportedOSPlatform("windows")]
public void SetAccessControl(object value)
{
GetMockDirectoryData().AccessControl = value as DirectorySecurity;
}

private MockDirectoryData GetMockDirectoryData()
{
return mockFileDataAccessor.GetFile(directoryPath) as MockDirectoryData
?? throw CommonExceptions.CouldNotFindPartOfPath(directoryPath);
}
}
}
40 changes: 0 additions & 40 deletions src/System.IO.Abstractions.TestingHelpers/MockFile.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Versioning;
using System.Security.AccessControl;
using System.Text;

namespace System.IO.Abstractions.TestingHelpers
Expand Down Expand Up @@ -268,28 +266,6 @@ public override bool Exists(string path)
return false;
}

/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override FileSecurity GetAccessControl(string path)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");

if (!mockFileDataAccessor.FileExists(path))
{
throw CommonExceptions.FileNotFound(path);
}

var fileData = mockFileDataAccessor.GetFile(path);
return fileData.AccessControl;
}

/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override FileSecurity GetAccessControl(string path, AccessControlSections includeSections)
{
return GetAccessControl(path);
}

/// <summary>
/// Gets the <see cref="FileAttributes"/> of the file on the path.
/// </summary>
Expand Down Expand Up @@ -732,22 +708,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi
}
#endif

/// <inheritdoc />
[SupportedOSPlatform("windows")]
public override void SetAccessControl(string path, FileSecurity fileSecurity)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");

if (!mockFileDataAccessor.FileExists(path))
{
throw CommonExceptions.FileNotFound(path);
}

var fileData = mockFileDataAccessor.GetFile(path);
mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime);
fileData.AccessControl = fileSecurity;
}

/// <inheritdoc />
public override void SetAttributes(string path, FileAttributes fileAttributes)
{
Expand Down
24 changes: 17 additions & 7 deletions src/System.IO.Abstractions.TestingHelpers/MockFileData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ public class MockFileData
public static readonly DateTimeOffset DefaultDateTimeOffset = new DateTime(1601, 01, 01, 00, 00, 00, DateTimeKind.Utc);

/// <summary>
/// The access control of the <see cref="MockFileData"/>.
/// The extensibility of the <see cref="MockFileData"/>.
/// </summary>
internal FileSystemExtensibility Extensibility
=> extensibility;

[NonSerialized]
private FileSecurity accessControl;
private FileSystemExtensibility extensibility = new FileSystemExtensibility();

/// <summary>
/// Gets a value indicating whether the <see cref="MockFileData"/> is a directory or not.
Expand Down Expand Up @@ -98,8 +101,8 @@ public MockFileData(MockFileData template)
{
throw new ArgumentNullException(nameof(template));
}

accessControl = template.accessControl;
extensibility.CloneFrom(template.extensibility);
Attributes = template.Attributes;
Contents = template.Contents.ToArray();
CreationTime = template.CreationTime;
Expand Down Expand Up @@ -179,7 +182,7 @@ public DateTimeOffset LastWriteTime
public FileAttributes Attributes { get; set; } = FileAttributes.Normal;

/// <summary>
/// Gets or sets <see cref="FileSecurity"/> of the <see cref="MockFileData"/>. This is the object that is returned for this <see cref="MockFileData"/> when calling <see cref="FileBase.GetAccessControl(string)"/>.
/// Gets or sets <see cref="FileSecurity"/> of the <see cref="MockFileData"/>.
/// </summary>
[SupportedOSPlatform("windows")]
public FileSecurity AccessControl
Expand All @@ -188,9 +191,16 @@ public FileSecurity AccessControl
{
// FileSecurity's constructor will throw PlatformNotSupportedException on non-Windows platform, so we initialize it in lazy way.
// This let's us use this class as long as we don't use AccessControl property.
return accessControl ?? (accessControl = new FileSecurity());
var value = Extensibility.RetrieveMetadata("AccessControl:FileSecurity");
if (value is not FileSecurity fileSecurity)
{
fileSecurity = new FileSecurity();
Extensibility.StoreMetadata("AccessControl:FileSecurity", fileSecurity);
}

return fileSecurity;
vbreuss marked this conversation as resolved.
Show resolved Hide resolved
}
set { accessControl = value; }
set { Extensibility.StoreMetadata("AccessControl:FileSecurity", value); }
}

/// <summary>
Expand Down
Loading