Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Directory.Version.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<!-- This must match the major and minor components of the referenced Microsoft.Extensions.* packages (and highest supported .NET TFM). -->
<VersionPrefix>10.0.0</VersionPrefix>
<VersionPrefix>10.1.0</VersionPrefix>
</PropertyGroup>
</Project>
50 changes: 42 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

It gives you:
- Extension methods to register the file validator in the DI container
- Easy configuration via appsettings.json or fluent configuration in code
- Easy configuration via `appsettings.json` or fluent configuration in code

> This package is the `Microsoft.Extensions.DependencyInjection` integration layer.
> The core validation logic lives in [`ByteGuard.FileValidator`](https://github.com/ByteGuard-HQ/byteguard-file-validator-net).

## Getting Started

### Installation
This package is published and installed via NuGet.
This package is published and installed via [NuGet](https://www.nuget.org/packages/ByteGuard.FileValidator.Extensions.DependencyInjection).

Reference the package in your project:
```bash
Expand All @@ -24,20 +24,31 @@ dotnet add package ByteGuard.FileValidator.Extensions.DependencyInjection
### Add to DI container
In your `Program.cs` (or `Startup.cs` in older projects), register the validator:

**Using inline configuration**
```csharp
using ByteGuard.FileValidator;
using ByteGuard.FileValidator.Extensions.DependencyInjection;

// Using inline configuration
builder.Services.AddFileValidator(options =>
{
options.AllowFileTypes(FileExtensions.Pdf, FileExtensions.Jpg, FileExtensions.Png);
options.FileSizeLimit = ByteSize.MegaBytes(25);
options.ThrowOnInvalidFiles(false);

// If an antimalware package has been added
options.Scanner = ScannerRegistration.Create<ScannerImplementation, ScannerImplementationOptions>(opts =>
{
// Refer to the individual scanner implementations for ScannerType value and possible options.
// ...
})
});
```

// Using configuration from appsettings.json
builder.Services.AddFileValidator(options => configuration.GetSection("FileValidatorConfiguration").Bind(options));
**Using configuration from appsettings.json with default "FileValidator" section name**
```csharp
builder.Services.AddFileValidator(builder.Configuration);
```

**Using configuration from appsettings.json with custom section name**
```csharp
builder.Services.AddFileValidator(builder.Configuration, "MySection");
```

### Injection & Usage
Expand Down Expand Up @@ -79,5 +90,28 @@ It's possible to configure the `FileValidator` through `appsettings.json`.
}
```

**With antimalware scanner**
It's possible to configure an antimalware scanner directly through `appsettings.json`.

> ℹ️ _Refer to the individual scanner implementations for `ScannerType` value and possible options._

```json
{
"FileValidatorConfiguration": {
"SupportedFileTypes": [ ".pdf", ".jpg", ".png" ],
"FileSizeLimit": 26214400,
"UnitFileSizeLimit": "25MB",
"ThrowExceptionOnInvalidFile": true,
"Scanner": {
"ScannerType": "...",
"Options": {
"OptionA": "...",
"OptionB": "..."
}
}
}
}
```

## License
_ByteGuard.FileValidator.Extensions.DpendencyInjection is Copyright © ByteGuard Contributors - Provided under the MIT license._
Binary file added assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@
<RepositoryType>git</RepositoryType>
<PackageTags>byteguard file-validator extensions dependency injection</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>icon.png</PackageIcon>
<Copyright>Copyright © ByteGuard Contributors</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ByteGuard.FileValidator" Version="1.0.0" />
<PackageReference Include="ByteGuard.FileValidator" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
<None Include="..\..\assets\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@ public class FileValidatorSettingsConfiguration
/// Whether to throw an exception if an unsupported/invalid file is encountered. Defaults to <c>true</c>.
/// </summary>
public bool ThrowExceptionOnInvalidFile { get; set; } = true;

/// <summary>
/// Configuration for the antimalware scanner to use.
/// </summary>
public ScannerRegistration? Scanner { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using ByteGuard.FileValidator.Scanners;
using Microsoft.Extensions.Configuration;

namespace ByteGuard.FileValidator.Extensions.DependencyInjection.Configuration;

/// <summary>
/// Registration information for an antimalware scanner.
/// </summary>
public sealed class ScannerRegistration
{
/// <summary>
/// Type of the scanner to register. Must be derived from IAntimalwareScanner.
/// </summary>
public string ScannerType { get; set; } = default!;

private Type? _scannerType;

/// <summary>
/// Gets or sets the <see cref="Type"/> of the scanner.
/// </summary>
public Type Type
{
get
{
if (_scannerType is not null)
return _scannerType;

_scannerType = Type.GetType(ScannerType, throwOnError: false)!;
return _scannerType;
}
set
{
_scannerType = value;
ScannerType = value.AssemblyQualifiedName!;
}
}

/// <summary>
/// Options for the scanner.
/// </summary>
public object? OptionsInstance { get; set; }

/// <summary>
/// Raw configuration section for options (for appsettings registration).
/// </summary>
public IConfigurationSection? OptionsConfiguration { get; set; }

/// <summary>
/// Creates a new <see cref="ScannerRegistration"/> instance for the specified scanner type and options.
/// </summary>
/// <param name="options">Scanner options.</param>
/// <typeparam name="TScanner">Scanner implementation inheriting from IAntimalwareScanner.</typeparam>
/// <typeparam name="TOptions">Scanner options.</typeparam>
public static ScannerRegistration Create<TScanner, TOptions>(Action<TOptions> options)
where TScanner : IAntimalwareScanner<TOptions>
where TOptions : class, new()
{
var opts = new TOptions();
options?.Invoke(opts);

return new ScannerRegistration
{
Type = typeof(TScanner),
OptionsInstance = opts
};
}

/// <summary>
/// Creates a new <see cref="ScannerRegistration"/> instance for the specified scanner type and options.
/// </summary>
/// <param name="options">Scanner options.</param>
/// <typeparam name="TScanner">Scanner implementation inheriting from IAntimalwareScanner.</typeparam>
/// <typeparam name="TOptions">Scanner options.</typeparam>
public static ScannerRegistration Create<TScanner, TOptions>(TOptions options)
where TScanner : IAntimalwareScanner<TOptions>
where TOptions : class, new()
{
return new ScannerRegistration
{
Type = typeof(TScanner),
OptionsInstance = options
};
}
}
Loading