Skip to content

Commit 24d1d07

Browse files
authored
refactor: extract ACL related functionality (#913)
Remove the ACL-Features from the interfaces and instead implement them as extension methods implemented in "TestableIO.System.IO.Abstractions.Wrappers". This removes the dependency on `System.IO.FileSystem.AccessControl` from the interface project. This is part of the approach discussed in #883 BREAKING CHANGE: This refactoring removes ACL-related methods from the interface project and replaces them with extension methods in `TestableIO.System.IO.Abstractions.Wrappers`.
1 parent b662500 commit 24d1d07

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+628
-499
lines changed

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectory.cs

+2-58
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
using System.Collections.Generic;
2-
using System.ComponentModel;
32
using System.Globalization;
43
using System.Linq;
5-
using System.Runtime.Versioning;
6-
using System.Security.AccessControl;
74
using System.Text.RegularExpressions;
85

96
namespace System.IO.Abstractions.TestingHelpers
@@ -39,17 +36,10 @@ public MockDirectory(IMockFileDataAccessor mockFileDataAccessor, string currentD
3936
/// <inheritdoc />
4037
public override IDirectoryInfo CreateDirectory(string path)
4138
{
42-
return CreateDirectoryInternal(path, null);
39+
return CreateDirectoryInternal(path);
4340
}
4441

45-
46-
/// <inheritdoc />
47-
public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity)
48-
{
49-
return CreateDirectoryInternal(path, directorySecurity);
50-
}
51-
52-
private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity directorySecurity)
42+
private IDirectoryInfo CreateDirectoryInternal(string path)
5343
{
5444
if (path == null)
5545
{
@@ -80,11 +70,6 @@ private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity di
8070

8171
var created = new MockDirectoryInfo(mockFileDataAccessor, path);
8272

83-
if (directorySecurity != null)
84-
{
85-
created.SetAccessControl(directorySecurity);
86-
}
87-
8873
return created;
8974
}
9075

@@ -173,31 +158,6 @@ public override bool Exists(string path)
173158
}
174159

175160

176-
/// <inheritdoc />
177-
[SupportedOSPlatform("windows")]
178-
public override DirectorySecurity GetAccessControl(string path)
179-
{
180-
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
181-
path = path.TrimSlashes();
182-
183-
if (!mockFileDataAccessor.Directory.Exists(path))
184-
{
185-
throw CommonExceptions.CouldNotFindPartOfPath(path);
186-
}
187-
188-
var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path);
189-
return directoryData.AccessControl;
190-
}
191-
192-
193-
/// <inheritdoc />
194-
[SupportedOSPlatform("windows")]
195-
public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections)
196-
{
197-
return GetAccessControl(path);
198-
}
199-
200-
201161
/// <inheritdoc />
202162
public override DateTime GetCreationTime(string path)
203163
{
@@ -559,22 +519,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi
559519

560520
#endif
561521

562-
/// <inheritdoc />
563-
[SupportedOSPlatform("windows")]
564-
public override void SetAccessControl(string path, DirectorySecurity directorySecurity)
565-
{
566-
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
567-
path = path.TrimSlashes();
568-
569-
if (!mockFileDataAccessor.Directory.Exists(path))
570-
{
571-
throw CommonExceptions.CouldNotFindPartOfPath(path);
572-
}
573-
574-
var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path);
575-
directoryData.AccessControl = directorySecurity;
576-
}
577-
578522
/// <inheritdoc />
579523
public override void SetCreationTime(string path, DateTime creationTime)
580524
{

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs

+41-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Runtime.Versioning;
34
using System.Security.AccessControl;
45

56
namespace System.IO.Abstractions.TestingHelpers
@@ -8,7 +9,7 @@ namespace System.IO.Abstractions.TestingHelpers
89

910
/// <inheritdoc />
1011
[Serializable]
11-
public class MockDirectoryInfo : DirectoryInfoBase
12+
public class MockDirectoryInfo : DirectoryInfoBase, IFileSystemAclSupport
1213
{
1314
private readonly IMockFileDataAccessor mockFileDataAccessor;
1415
private readonly string directoryPath;
@@ -26,6 +27,15 @@ public MockDirectoryInfo(IMockFileDataAccessor mockFileDataAccessor, string dire
2627
{
2728
this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor));
2829

30+
if (directoryPath == null)
31+
{
32+
throw new ArgumentNullException("path", StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL"));
33+
}
34+
if (directoryPath.Trim() == string.Empty)
35+
{
36+
throw CommonExceptions.PathIsNotOfALegalForm("path");
37+
}
38+
2939
originalPath = directoryPath;
3040
directoryPath = mockFileDataAccessor.Path.GetFullPath(directoryPath);
3141

@@ -179,14 +189,7 @@ public override void Create()
179189
mockFileDataAccessor.Directory.CreateDirectory(FullName);
180190
refreshOnNextRead = true;
181191
}
182-
183-
/// <inheritdoc />
184-
public override void Create(DirectorySecurity directorySecurity)
185-
{
186-
mockFileDataAccessor.Directory.CreateDirectory(FullName, directorySecurity);
187-
refreshOnNextRead = true;
188-
}
189-
192+
190193
/// <inheritdoc />
191194
public override IDirectoryInfo CreateSubdirectory(string path)
192195
{
@@ -277,19 +280,7 @@ public override IEnumerable<IFileSystemInfo> EnumerateFileSystemInfos(string sea
277280
return GetFileSystemInfos(searchPattern, enumerationOptions);
278281
}
279282
#endif
280-
281-
/// <inheritdoc />
282-
public override DirectorySecurity GetAccessControl()
283-
{
284-
return mockFileDataAccessor.Directory.GetAccessControl(directoryPath);
285-
}
286-
287-
/// <inheritdoc />
288-
public override DirectorySecurity GetAccessControl(AccessControlSections includeSections)
289-
{
290-
return mockFileDataAccessor.Directory.GetAccessControl(directoryPath, includeSections);
291-
}
292-
283+
293284
/// <inheritdoc />
294285
public override IDirectoryInfo[] GetDirectories()
295286
{
@@ -388,13 +379,7 @@ public override void MoveTo(string destDirName)
388379
{
389380
mockFileDataAccessor.Directory.Move(directoryPath, destDirName);
390381
}
391-
392-
/// <inheritdoc />
393-
public override void SetAccessControl(DirectorySecurity directorySecurity)
394-
{
395-
mockFileDataAccessor.Directory.SetAccessControl(directoryPath, directorySecurity);
396-
}
397-
382+
398383
/// <inheritdoc />
399384
public override IDirectoryInfo Parent
400385
{
@@ -435,5 +420,32 @@ public override string ToString()
435420
{
436421
return originalPath;
437422
}
423+
424+
/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl()" />
425+
[SupportedOSPlatform("windows")]
426+
public object GetAccessControl()
427+
{
428+
return GetMockDirectoryData().AccessControl;
429+
}
430+
431+
/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl(IFileSystemAclSupport.AccessControlSections)" />
432+
[SupportedOSPlatform("windows")]
433+
public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections)
434+
{
435+
return GetMockDirectoryData().AccessControl;
436+
}
437+
438+
/// <inheritdoc cref="IFileSystemAclSupport.SetAccessControl(object)" />
439+
[SupportedOSPlatform("windows")]
440+
public void SetAccessControl(object value)
441+
{
442+
GetMockDirectoryData().AccessControl = value as DirectorySecurity;
443+
}
444+
445+
private MockDirectoryData GetMockDirectoryData()
446+
{
447+
return mockFileDataAccessor.GetFile(directoryPath) as MockDirectoryData
448+
?? throw CommonExceptions.CouldNotFindPartOfPath(directoryPath);
449+
}
438450
}
439451
}

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.cs

-40
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System.Collections.Generic;
22
using System.Globalization;
33
using System.Linq;
4-
using System.Runtime.Versioning;
5-
using System.Security.AccessControl;
64
using System.Text;
75

86
namespace System.IO.Abstractions.TestingHelpers
@@ -268,28 +266,6 @@ public override bool Exists(string path)
268266
return false;
269267
}
270268

271-
/// <inheritdoc />
272-
[SupportedOSPlatform("windows")]
273-
public override FileSecurity GetAccessControl(string path)
274-
{
275-
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
276-
277-
if (!mockFileDataAccessor.FileExists(path))
278-
{
279-
throw CommonExceptions.FileNotFound(path);
280-
}
281-
282-
var fileData = mockFileDataAccessor.GetFile(path);
283-
return fileData.AccessControl;
284-
}
285-
286-
/// <inheritdoc />
287-
[SupportedOSPlatform("windows")]
288-
public override FileSecurity GetAccessControl(string path, AccessControlSections includeSections)
289-
{
290-
return GetAccessControl(path);
291-
}
292-
293269
/// <summary>
294270
/// Gets the <see cref="FileAttributes"/> of the file on the path.
295271
/// </summary>
@@ -732,22 +708,6 @@ public override IFileSystemInfo ResolveLinkTarget(string linkPath, bool returnFi
732708
}
733709
#endif
734710

735-
/// <inheritdoc />
736-
[SupportedOSPlatform("windows")]
737-
public override void SetAccessControl(string path, FileSecurity fileSecurity)
738-
{
739-
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
740-
741-
if (!mockFileDataAccessor.FileExists(path))
742-
{
743-
throw CommonExceptions.FileNotFound(path);
744-
}
745-
746-
var fileData = mockFileDataAccessor.GetFile(path);
747-
mockFileDataAccessor.AdjustTimes(fileData, TimeAdjustments.LastAccessTime);
748-
fileData.AccessControl = fileSecurity;
749-
}
750-
751711
/// <inheritdoc />
752712
public override void SetAttributes(string path, FileAttributes fileAttributes)
753713
{

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileData.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public string TextContents
133133
public DateTimeOffset CreationTime
134134
{
135135
get { return creationTime; }
136-
set{ creationTime = value.ToUniversalTime(); }
136+
set { creationTime = value.ToUniversalTime(); }
137137
}
138138
private DateTimeOffset creationTime;
139139

@@ -179,7 +179,7 @@ public static implicit operator MockFileData(string s)
179179
public FileAttributes Attributes { get; set; } = FileAttributes.Normal;
180180

181181
/// <summary>
182-
/// 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)"/>.
182+
/// Gets or sets <see cref="FileSecurity"/> of the <see cref="MockFileData"/>.
183183
/// </summary>
184184
[SupportedOSPlatform("windows")]
185185
public FileSecurity AccessControl

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileInfo.cs

+32-25
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace System.IO.Abstractions.TestingHelpers
55
{
66
/// <inheritdoc />
77
[Serializable]
8-
public class MockFileInfo : FileInfoBase
8+
public class MockFileInfo : FileInfoBase, IFileSystemAclSupport
99
{
1010
private readonly IMockFileDataAccessor mockFileSystem;
1111
private string path;
@@ -18,7 +18,8 @@ public class MockFileInfo : FileInfoBase
1818
public MockFileInfo(IMockFileDataAccessor mockFileSystem, string path) : base(mockFileSystem?.FileSystem)
1919
{
2020
this.mockFileSystem = mockFileSystem ?? throw new ArgumentNullException(nameof(mockFileSystem));
21-
this.originalPath = path ?? throw new ArgumentNullException(nameof(path));
21+
mockFileSystem.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
22+
this.originalPath = path;
2223
this.path = mockFileSystem.Path.GetFullPath(path);
2324
this.mockFile = new MockFile(mockFileSystem);
2425
Refresh();
@@ -256,21 +257,7 @@ public override void Encrypt()
256257
var mockFileData = GetMockFileDataForWrite();
257258
mockFileData.Attributes |= FileAttributes.Encrypted;
258259
}
259-
260-
/// <inheritdoc />
261-
[SupportedOSPlatform("windows")]
262-
public override FileSecurity GetAccessControl()
263-
{
264-
return mockFileSystem.File.GetAccessControl(this.path);
265-
}
266-
267-
/// <inheritdoc />
268-
[SupportedOSPlatform("windows")]
269-
public override FileSecurity GetAccessControl(AccessControlSections includeSections)
270-
{
271-
return mockFileSystem.File.GetAccessControl(this.path, includeSections);
272-
}
273-
260+
274261
/// <inheritdoc />
275262
public override void MoveTo(string destFileName)
276263
{
@@ -334,14 +321,7 @@ public override IFileInfo Replace(string destinationFileName, string destination
334321
mockFile.Replace(path, destinationFileName, destinationBackupFileName, ignoreMetadataErrors);
335322
return mockFileSystem.FileInfo.New(destinationFileName);
336323
}
337-
338-
/// <inheritdoc />
339-
[SupportedOSPlatform("windows")]
340-
public override void SetAccessControl(FileSecurity fileSecurity)
341-
{
342-
mockFile.SetAccessControl(this.path, fileSecurity);
343-
}
344-
324+
345325
/// <inheritdoc />
346326
public override IDirectoryInfo Directory
347327
{
@@ -404,6 +384,33 @@ public override string ToString()
404384
return originalPath;
405385
}
406386

387+
/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl()" />
388+
[SupportedOSPlatform("windows")]
389+
public object GetAccessControl()
390+
{
391+
return GetMockFileData().AccessControl;
392+
}
393+
394+
/// <inheritdoc cref="IFileSystemAclSupport.GetAccessControl(IFileSystemAclSupport.AccessControlSections)" />
395+
[SupportedOSPlatform("windows")]
396+
public object GetAccessControl(IFileSystemAclSupport.AccessControlSections includeSections)
397+
{
398+
return GetMockFileData().AccessControl;
399+
}
400+
401+
/// <inheritdoc cref="IFileSystemAclSupport.SetAccessControl(object)" />
402+
[SupportedOSPlatform("windows")]
403+
public void SetAccessControl(object value)
404+
{
405+
GetMockFileData().AccessControl = value as FileSecurity;
406+
}
407+
408+
private MockFileData GetMockFileData()
409+
{
410+
return mockFileSystem.GetFile(path)
411+
?? throw CommonExceptions.FileNotFound(path);
412+
}
413+
407414
private static DateTime AdjustUnspecifiedKind(DateTime time, DateTimeKind fallbackKind)
408415
{
409416
if (time.Kind == DateTimeKind.Unspecified)

0 commit comments

Comments
 (0)