Skip to content

Commit 9929a94

Browse files
committed
Add features to easy validate types in web projects
1 parent 25112a1 commit 9929a94

File tree

7 files changed

+221
-0
lines changed

7 files changed

+221
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace FileTypeChecker.Web.Attributes
2+
{
3+
using FileTypeChecker.Web.Infrastructure;
4+
using Microsoft.AspNetCore.Http;
5+
using System;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.IO;
8+
using System.Linq;
9+
10+
[AttributeUsage(AttributeTargets.Property)]
11+
public class AllowedTypesAttribute : ValidationAttribute
12+
{
13+
private readonly string[] extensions;
14+
15+
public AllowedTypesAttribute(params string[] extensions)
16+
=> this.extensions = extensions;
17+
18+
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
19+
{
20+
if (!(value is IFormFile file))
21+
{
22+
return ValidationResult.Success;
23+
}
24+
25+
using var stream = new MemoryStream();
26+
file.CopyTo(stream);
27+
28+
if (!FileTypeValidator.IsTypeRecognizable(stream))
29+
{
30+
return new ValidationResult(Constants.ErrorMessages.UnsupportedFileErrorMessage);
31+
}
32+
33+
var fileType = FileTypeValidator.GetFileType(stream);
34+
35+
if (!extensions.Contains(fileType.Extension.ToLower()))
36+
{
37+
return new ValidationResult(Constants.ErrorMessages.InvalidFileTypeErrorMessage);
38+
}
39+
40+
return ValidationResult.Success;
41+
}
42+
}
43+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace FileTypeChecker.Web.Attributes
2+
{
3+
using FileTypeChecker.Extensions;
4+
using FileTypeChecker.Types;
5+
using FileTypeChecker.Web.Infrastructure;
6+
using Microsoft.AspNetCore.Http;
7+
using System;
8+
using System.ComponentModel.DataAnnotations;
9+
using System.IO;
10+
11+
[AttributeUsage(AttributeTargets.Property)]
12+
public class ForbidExecutableFileAttribute : ValidationAttribute
13+
{
14+
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
15+
{
16+
if (!(value is IFormFile file))
17+
{
18+
return ValidationResult.Success;
19+
}
20+
21+
using var stream = new MemoryStream();
22+
file.CopyTo(stream);
23+
24+
if (!FileTypeValidator.IsTypeRecognizable(stream))
25+
{
26+
return new ValidationResult(Constants.ErrorMessages.UnsupportedFileErrorMessage);
27+
}
28+
29+
if (stream.Is<Executable>() || stream.Is<ExecutableAndLinkableFormat>())
30+
{
31+
return new ValidationResult(Constants.ErrorMessages.InvalidFileTypeErrorMessage);
32+
}
33+
34+
return ValidationResult.Success;
35+
}
36+
}
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace FileTypeChecker.Web.Attributes
2+
{
3+
using FileTypeChecker.Web.Infrastructure;
4+
using Microsoft.AspNetCore.Http;
5+
using System;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.IO;
8+
using System.Linq;
9+
10+
11+
[AttributeUsage(AttributeTargets.Property)]
12+
public class ForbidTypesAttribute : ValidationAttribute
13+
{
14+
private readonly string[] extensions;
15+
16+
public ForbidTypesAttribute(params string[] extensions)
17+
=> this.extensions = extensions;
18+
19+
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
20+
{
21+
if (!(value is IFormFile file))
22+
{
23+
return ValidationResult.Success;
24+
}
25+
26+
using var stream = new MemoryStream();
27+
file.CopyTo(stream);
28+
29+
if (!FileTypeValidator.IsTypeRecognizable(stream))
30+
{
31+
return new ValidationResult(Constants.ErrorMessages.UnsupportedFileErrorMessage);
32+
}
33+
34+
var fileType = FileTypeValidator.GetFileType(stream);
35+
36+
if (extensions.Contains(fileType.Extension.ToLower()))
37+
{
38+
return new ValidationResult(Constants.ErrorMessages.InvalidFileTypeErrorMessage);
39+
}
40+
41+
return ValidationResult.Success;
42+
}
43+
}
44+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace FileTypeChecker.Web.Attributes
2+
{
3+
using FileTypeChecker.Extensions;
4+
using FileTypeChecker.Web.Infrastructure;
5+
using Microsoft.AspNetCore.Http;
6+
using System;
7+
using System.ComponentModel.DataAnnotations;
8+
using System.IO;
9+
10+
[AttributeUsage(AttributeTargets.Property)]
11+
public class OnlyArchiveAttribute : ValidationAttribute
12+
{
13+
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
14+
{
15+
if (!(value is IFormFile file))
16+
{
17+
return ValidationResult.Success;
18+
}
19+
20+
using var stream = new MemoryStream();
21+
file.CopyTo(stream);
22+
23+
if (!FileTypeValidator.IsTypeRecognizable(stream))
24+
{
25+
return new ValidationResult(Constants.ErrorMessages.UnsupportedFileErrorMessage);
26+
}
27+
28+
if (!stream.IsArchive())
29+
{
30+
return new ValidationResult(Constants.ErrorMessages.InvalidFileTypeErrorMessage);
31+
}
32+
33+
return ValidationResult.Success;
34+
}
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace FileTypeChecker.Web.Attributes
2+
{
3+
using FileTypeChecker.Extensions;
4+
using FileTypeChecker.Web.Infrastructure;
5+
using Microsoft.AspNetCore.Http;
6+
using System;
7+
using System.ComponentModel.DataAnnotations;
8+
using System.IO;
9+
10+
[AttributeUsage(AttributeTargets.Property)]
11+
public class OnlyImageAttribute : ValidationAttribute
12+
{
13+
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
14+
{
15+
if (!(value is IFormFile file))
16+
{
17+
return ValidationResult.Success;
18+
}
19+
20+
using var stream = new MemoryStream();
21+
file.CopyTo(stream);
22+
23+
if (!FileTypeValidator.IsTypeRecognizable(stream))
24+
{
25+
return new ValidationResult(Constants.ErrorMessages.UnsupportedFileErrorMessage);
26+
}
27+
28+
if (!stream.IsImage())
29+
{
30+
return new ValidationResult(Constants.ErrorMessages.InvalidFileTypeErrorMessage);
31+
}
32+
33+
return ValidationResult.Success;
34+
}
35+
}
36+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>8.0</LangVersion>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="File.TypeChecker" Version="1.3.0" />
10+
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.3" />
11+
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace FileTypeChecker.Web.Infrastructure
2+
{
3+
internal static class Constants
4+
{
5+
internal static class ErrorMessages
6+
{
7+
public const string UnsupportedFileErrorMessage = "Provided file is not of supported type. Please provide a valid file!";
8+
public const string InvalidFileTypeErrorMessage = "This type of file is not allowed!";
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)