Skip to content

Commit f88e28d

Browse files
Filesystem: Prevent tree showing other filetypes than the supported ones (#20567)
* Added check to only find .css files in FileSystemTreeServiceBase.cs * Marking GetFiles as virtual and overriding it in StyleSheetTreeService.cs to only find .css files * Redone tests to fit new format * Fix tests to use file extensions * Adding file extensions to all other relevant tests * Adding file filter to remaining trees * Adding tests to ensure invalid filetypes wont show * Encapulation and resolved minor warnings in tests. --------- Co-authored-by: Andy Butland <[email protected]>
1 parent 194fee7 commit f88e28d

File tree

8 files changed

+90
-26
lines changed

8 files changed

+90
-26
lines changed

src/Umbraco.Cms.Api.Management/Services/FileSystem/FileSystemTreeServiceBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ public string[] GetDirectories(string path) => FileSystem
7575

7676
public string[] GetFiles(string path) => FileSystem
7777
.GetFiles(path)
78+
.Where(FilterFile)
7879
.OrderBy(file => file)
7980
.ToArray();
8081

82+
protected virtual bool FilterFile(string file) => true;
83+
8184
public bool DirectoryHasChildren(string path)
8285
=> FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
8386

src/Umbraco.Cms.Api.Management/Services/FileSystem/PartialViewTreeService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ public class PartialViewTreeService : FileSystemTreeServiceBase, IPartialViewTre
1111
public PartialViewTreeService(FileSystems fileSystems) =>
1212
_partialViewFileSystem = fileSystems.PartialViewsFileSystem ??
1313
throw new ArgumentException("Missing partial views file system", nameof(fileSystems));
14+
15+
protected override bool FilterFile(string file) => file.ToLowerInvariant().EndsWith(".cshtml");
1416
}

src/Umbraco.Cms.Api.Management/Services/FileSystem/ScriptTreeService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ public class ScriptTreeService : FileSystemTreeServiceBase, IScriptTreeService
1111
public ScriptTreeService(FileSystems fileSystems) =>
1212
_scriptFileSystem = fileSystems.ScriptsFileSystem ??
1313
throw new ArgumentException("Missing partial views file system", nameof(fileSystems));
14+
15+
protected override bool FilterFile(string file) => file.ToLowerInvariant().EndsWith(".js");
1416
}

src/Umbraco.Cms.Api.Management/Services/FileSystem/StyleSheetTreeService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ public class StyleSheetTreeService : FileSystemTreeServiceBase, IStyleSheetTreeS
1010

1111
public StyleSheetTreeService(FileSystems fileSystems) =>
1212
_scriptFileSystem = fileSystems.StylesheetsFileSystem ??
13-
throw new ArgumentException("Missing partial views file system", nameof(fileSystems));
13+
throw new ArgumentException("Missing stylesheets file system", nameof(fileSystems));
14+
15+
protected override bool FilterFile(string file) => file.ToLowerInvariant().EndsWith(".css");
1416
}

tests/Umbraco.Tests.Integration/ManagementApi/Services/Trees/FileSystemTreeServiceTestsBase.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ public abstract class FileSystemTreeServiceTestsBase : UmbracoIntegrationTest
1616

1717
protected IFileSystem TestFileSystem { get; private set; }
1818

19+
protected abstract string FileExtension { get; set; }
20+
1921
protected abstract string FileSystemPath { get; }
2022

2123
protected IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
2224

2325
[SetUp]
24-
public void SetUpFileSystem()
26+
public virtual void SetUpFileSystem()
2527
{
2628
TestFileSystem = new PhysicalFileSystem(IOHelper, HostingEnvironment, LoggerFactory.CreateLogger<PhysicalFileSystem>(), HostingEnvironment.MapPathWebRoot(FileSystemPath), HostingEnvironment.ToAbsolute(FileSystemPath));
2729

@@ -37,11 +39,11 @@ public void SetUpFileSystem()
3739
for (int i = 0; i < 10; i++)
3840
{
3941
using var stream = CreateStream(Path.Join("tests"));
40-
TestFileSystem.AddFile($"file{i}", stream);
42+
TestFileSystem.AddFile($"file{i}{FileExtension}", stream);
4143
}
4244
}
4345

44-
private static Stream CreateStream(string contents = null)
46+
protected static Stream CreateStream(string contents = null)
4547
{
4648
if (string.IsNullOrEmpty(contents))
4749
{
@@ -59,7 +61,7 @@ private static Stream CreateStream(string contents = null)
5961
protected virtual IFileSystem? GetScriptsFileSystem() => null;
6062

6163
[TearDown]
62-
public void TearDownFileSystem()
64+
public virtual void TearDownFileSystem()
6365
{
6466
Purge(TestFileSystem, string.Empty);
6567
FileSystems = null;

tests/Umbraco.Tests.Integration/ManagementApi/Services/Trees/PartialViewTreeServiceTests.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services.Trees;
88

99
public class PartialViewTreeServiceTests : FileSystemTreeServiceTestsBase
1010
{
11+
protected override string FileExtension { get; set; } = ".cshtml";
12+
1113
protected override string FileSystemPath => Constants.SystemDirectories.PartialViews;
1214

1315
protected override IFileSystem? GetPartialViewsFileSystem() => TestFileSystem;
@@ -17,12 +19,12 @@ public void Can_Get_Siblings_From_PartialView_Tree_Service()
1719
{
1820
var service = new PartialViewTreeService(FileSystems);
1921

20-
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels("file5", 1, 1, out long before, out var after);
21-
int index = Array.FindIndex(treeModel, item => item.Name == "file5");
22+
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels($"file5{FileExtension}", 1, 1, out long before, out var after);
23+
int index = Array.FindIndex(treeModel, item => item.Name == $"file5{FileExtension}");
2224

23-
Assert.AreEqual(treeModel[index].Name, "file5");
24-
Assert.AreEqual(treeModel[index - 1].Name, "file4");
25-
Assert.AreEqual(treeModel[index + 1].Name, "file6");
25+
Assert.AreEqual(treeModel[index].Name, $"file5{FileExtension}");
26+
Assert.AreEqual(treeModel[index - 1].Name, $"file4{FileExtension}");
27+
Assert.AreEqual(treeModel[index + 1].Name, $"file6{FileExtension}");
2628
Assert.That(treeModel.Length == 3);
2729
Assert.AreEqual(after, 3);
2830
Assert.AreEqual(before, 4);
@@ -33,7 +35,7 @@ public void Can_Get_Ancestors_From_StyleSheet_Tree_Service()
3335
{
3436
var service = new PartialViewTreeService(FileSystems);
3537

36-
var path = Path.Join("tests", "file5");
38+
var path = Path.Join("tests", $"file5{FileExtension}");
3739
FileSystemTreeItemPresentationModel[] treeModel = service.GetAncestorModels(path, true);
3840

3941
Assert.IsNotEmpty(treeModel);
@@ -46,9 +48,25 @@ public void Can_Get_PathViewModels_From_StyleSheet_Tree_Service()
4648
{
4749
var service = new PartialViewTreeService(FileSystems);
4850

49-
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, Int32.MaxValue, out var totalItems);
51+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
5052

5153
Assert.IsNotEmpty(treeModels);
5254
Assert.AreEqual(treeModels.Length, totalItems);
5355
}
56+
57+
[Test]
58+
public void Will_Hide_Unsupported_File_Extensions()
59+
{
60+
var service = new PartialViewTreeService(FileSystems);
61+
for (int i = 0; i < 2; i++)
62+
{
63+
using var stream = CreateStream(Path.Join("tests"));
64+
TestFileSystem.AddFile($"file{i}.invalid", stream);
65+
}
66+
67+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
68+
69+
Assert.IsEmpty(treeModels.Where(file => file.Name.Contains(".invalid")));
70+
Assert.AreEqual(treeModels.Length, totalItems);
71+
}
5472
}

tests/Umbraco.Tests.Integration/ManagementApi/Services/Trees/ScriptTreeServiceTests.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services.Trees;
77

88
public class ScriptTreeServiceTests : FileSystemTreeServiceTestsBase
99
{
10+
protected override string FileExtension { get; set; } = ".js";
1011
protected override string FileSystemPath => GlobalSettings.UmbracoScriptsPath;
1112

1213
protected override IFileSystem? GetScriptsFileSystem() => TestFileSystem;
@@ -16,12 +17,12 @@ public void Can_Get_Siblings_From_Script_Tree_Service()
1617
{
1718
var service = new ScriptTreeService(FileSystems);
1819

19-
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels("file5", 1, 1, out long before, out var after);
20-
int index = Array.FindIndex(treeModel, item => item.Name == "file5");
20+
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels($"file5{FileExtension}", 1, 1, out long before, out var after);
21+
int index = Array.FindIndex(treeModel, item => item.Name == $"file5{FileExtension}");
2122

22-
Assert.AreEqual(treeModel[index].Name, "file5");
23-
Assert.AreEqual(treeModel[index - 1].Name, "file4");
24-
Assert.AreEqual(treeModel[index + 1].Name, "file6");
23+
Assert.AreEqual(treeModel[index].Name, $"file5{FileExtension}");
24+
Assert.AreEqual(treeModel[index - 1].Name, $"file4{FileExtension}");
25+
Assert.AreEqual(treeModel[index + 1].Name, $"file6{FileExtension}");
2526
Assert.That(treeModel.Length == 3);
2627
Assert.AreEqual(after, 3);
2728
Assert.AreEqual(before, 4);
@@ -32,7 +33,7 @@ public void Can_Get_Ancestors_From_StyleSheet_Tree_Service()
3233
{
3334
var service = new ScriptTreeService(FileSystems);
3435

35-
var path = Path.Join("tests", "file5");
36+
var path = Path.Join("tests", $"file5{FileExtension}");
3637
FileSystemTreeItemPresentationModel[] treeModel = service.GetAncestorModels(path, true);
3738

3839
Assert.IsNotEmpty(treeModel);
@@ -45,9 +46,25 @@ public void Can_Get_PathViewModels_From_StyleSheet_Tree_Service()
4546
{
4647
var service = new ScriptTreeService(FileSystems);
4748

48-
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, Int32.MaxValue, out var totalItems);
49+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
4950

5051
Assert.IsNotEmpty(treeModels);
5152
Assert.AreEqual(treeModels.Length, totalItems);
5253
}
54+
55+
[Test]
56+
public void Will_Hide_Unsupported_File_Extensions()
57+
{
58+
var service = new ScriptTreeService(FileSystems);
59+
for (int i = 0; i < 2; i++)
60+
{
61+
using var stream = CreateStream(Path.Join("tests"));
62+
TestFileSystem.AddFile($"file{i}.invalid", stream);
63+
}
64+
65+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
66+
67+
Assert.IsEmpty(treeModels.Where(file => file.Name.Contains(".invalid")));
68+
Assert.AreEqual(treeModels.Length, totalItems);
69+
}
5370
}

tests/Umbraco.Tests.Integration/ManagementApi/Services/Trees/StyleSheetTreeServiceTests.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services.Trees;
77

88
public class StyleSheetTreeServiceTests : FileSystemTreeServiceTestsBase
99
{
10+
protected override string FileExtension { get; set; } = ".css";
11+
1012
protected override string FileSystemPath => GlobalSettings.UmbracoCssPath;
1113

1214
protected override IFileSystem? GetStylesheetsFileSystem() => TestFileSystem;
@@ -16,12 +18,12 @@ public void Can_Get_Siblings_From_StyleSheet_Tree_Service()
1618
{
1719
var service = new StyleSheetTreeService(FileSystems);
1820

19-
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels("file5", 1, 1, out long before, out var after);
20-
int index = Array.FindIndex(treeModel, item => item.Name == "file5");
21+
FileSystemTreeItemPresentationModel[] treeModel = service.GetSiblingsViewModels($"file5{FileExtension}", 1, 1, out long before, out var after);
22+
int index = Array.FindIndex(treeModel, item => item.Name == $"file5{FileExtension}");
2123

22-
Assert.AreEqual(treeModel[index].Name, "file5");
23-
Assert.AreEqual(treeModel[index - 1].Name, "file4");
24-
Assert.AreEqual(treeModel[index + 1].Name, "file6");
24+
Assert.AreEqual(treeModel[index].Name, $"file5{FileExtension}");
25+
Assert.AreEqual(treeModel[index - 1].Name, $"file4{FileExtension}");
26+
Assert.AreEqual(treeModel[index + 1].Name, $"file6{FileExtension}");
2527
Assert.That(treeModel.Length == 3);
2628
Assert.AreEqual(after, 3);
2729
Assert.AreEqual(before, 4);
@@ -32,7 +34,7 @@ public void Can_Get_Ancestors_From_StyleSheet_Tree_Service()
3234
{
3335
var service = new StyleSheetTreeService(FileSystems);
3436

35-
var path = Path.Join("tests", "file5");
37+
var path = Path.Join("tests", $"file5{FileExtension}");
3638
FileSystemTreeItemPresentationModel[] treeModel = service.GetAncestorModels(path, true);
3739

3840
Assert.IsNotEmpty(treeModel);
@@ -45,9 +47,25 @@ public void Can_Get_PathViewModels_From_StyleSheet_Tree_Service()
4547
{
4648
var service = new StyleSheetTreeService(FileSystems);
4749

48-
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, Int32.MaxValue, out var totalItems);
50+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
4951

5052
Assert.IsNotEmpty(treeModels);
5153
Assert.AreEqual(treeModels.Length, totalItems);
5254
}
55+
56+
[Test]
57+
public void Will_Hide_Unsupported_File_Extensions()
58+
{
59+
var service = new StyleSheetTreeService(FileSystems);
60+
for (int i = 0; i < 2; i++)
61+
{
62+
using var stream = CreateStream(Path.Join("tests"));
63+
TestFileSystem.AddFile($"file{i}.invalid", stream);
64+
}
65+
66+
FileSystemTreeItemPresentationModel[] treeModels = service.GetPathViewModels(string.Empty, 0, int.MaxValue, out var totalItems);
67+
68+
Assert.IsEmpty(treeModels.Where(file => file.Name.Contains(".invalid")));
69+
Assert.AreEqual(treeModels.Length, totalItems);
70+
}
5371
}

0 commit comments

Comments
 (0)