Skip to content

Commit b1da634

Browse files
authored
Release/v5.1.0
* - Add changes for v5.1.0
1 parent 3545fe4 commit b1da634

File tree

57 files changed

+2560
-214
lines changed

Some content is hidden

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

57 files changed

+2560
-214
lines changed

GitVersion.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
next-version: 5.0.1
1+
next-version: 5.1.0
22
tag-prefix: '[vV]'
33
mode: ContinuousDeployment
44
branches:

README.md

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

2-
# <img src="https://github.com/NinjaRocks/FeatureOne/blob/master/ninja-icon-16.png" alt="ninja" style="width:30px;"/> FeatureOne v5.0.1
3-
[![GitHub Release](https://img.shields.io/github/v/release/ninjarocks/FeatureOne?logo=github&sort=semver)](https://github.com/ninjarocks/FeatureOne/releases/latest)
4-
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/NinjaRocks/FeatureOne/blob/master/License.md) [![build-master](https://github.com/NinjaRocks/FeatureOne/actions/workflows/Build-Master.yml/badge.svg)](https://github.com/NinjaRocks/FeatureOne/actions/workflows/Build-Master.yml)
5-
[![CodeQL](https://github.com/NinjaRocks/FeatureOne/actions/workflows/codeql.yml/badge.svg)](https://github.com/NinjaRocks/FeatureOne/actions/workflows/codeql.yml)
2+
# <img src="https://github.com/CodeShayk/FeatureOne/blob/master/ninja-icon-16.png" alt="ninja" style="width:30px;"/> FeatureOne v5.1.0
3+
[![GitHub Release](https://img.shields.io/github/v/release/CodeShayk/FeatureOne?logo=github&sort=semver)](https://github.com/CodeShayk/FeatureOne/releases/latest)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/CodeShayk/FeatureOne/blob/master/License.md) [![build-master](https://github.com/CodeShayk/FeatureOne/actions/workflows/Build-Master.yml/badge.svg)](https://github.com/CodeShayk/FeatureOne/actions/workflows/Build-Master.yml)
5+
[![CodeQL](https://github.com/CodeShayk/FeatureOne/actions/workflows/codeql.yml/badge.svg)](https://github.com/CodeShayk/FeatureOne/actions/workflows/codeql.yml)
66
[![.Net](https://img.shields.io/badge/.Net_Framework-4.6.2-blue)](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net46)
77
[![.Net](https://img.shields.io/badge/.Net_Standard-2.1-blue)](https://dotnet.microsoft.com/en-us/download/netstandard/2.1)
88
[![.Net](https://img.shields.io/badge/.Net-9.0-blue)](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)
@@ -12,9 +12,9 @@
1212
#### Nuget Packages
1313
| Package | Latest | Details |
1414
| --------| --------| --------|
15-
|FeatureOne |[![NuGet version](https://badge.fury.io/nu/FeatureOne.svg)](https://badge.fury.io/nu/FeatureOne) | Provides core funtionality to implement feature toggles with `no` backend storage provider. Needs package consumer to provide `IStorageProvider` implementation. Ideal for use case that requires custom storage backend. Please see below for more details. |
16-
|FeatureOne.SQL| [![NuGet version](https://badge.fury.io/nu/FeatureOne.SQL.svg)](https://badge.fury.io/nu/FeatureOne.SQL) | Provides SQL storage provider for implementing feature toggles using `SQL` backend. |
17-
|FeatureOne.File |[![NuGet version](https://badge.fury.io/nu/FeatureOne.File.svg)](https://badge.fury.io/nu/FeatureOne.File) | Provides File storage provider for implementing feature toggles using `File System` backend. |
15+
|FeatureOne |[![NuGet version](https://badge.fury.io/nu/FeatureOne.svg)](https://badge.fury.io/nu/FeatureOne) | Provides core functionality to implement feature toggles with `no` backend storage provider. Needs package consumer to provide `IStorageProvider` implementation. Ideal for use case that requires custom storage backend. **v5.1.0**: Security fixes, DI integration, DateRangeCondition. |
16+
|FeatureOne.SQL| [![NuGet version](https://badge.fury.io/nu/FeatureOne.SQL.svg)](https://badge.fury.io/nu/FeatureOne.SQL) | Provides SQL storage provider for implementing feature toggles using `SQL` backend. **v5.1.0**: Security fixes, DI integration, enhanced configuration. |
17+
|FeatureOne.File |[![NuGet version](https://badge.fury.io/nu/FeatureOne.File.svg)](https://badge.fury.io/nu/FeatureOne.File) | Provides File storage provider for implementing feature toggles using `File System` backend. **v5.1.0**: Security fixes, DI integration, enhanced configuration. |
1818

1919
## Concept
2020
### What is a feature toggle?
@@ -58,12 +58,22 @@ If you are having problems, please let me know by [raising a new issue](https://
5858
This project is licensed with the [MIT license](LICENSE).
5959

6060
## Version History
61-
The main branch is now on .NET 9.0. The following previous versions are available:
62-
| Version | Release Notes | Developer Guide |
63-
| -------- | --------|--------|
64-
| [`v4.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v4.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v4.0.0) | [Guide](https://github.com/CodeShayk/FeatureOne/blob/v4.0.0/DeveloperGuide.md) |
65-
| [`v3.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v3.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v3.0.0) | [Guide](https://github.com/CodeShayk/FeatureOne/blob/v3.0.0/DeveloperGuide.md) |
66-
| [`v2.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v2.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v2.0.0) | [Guide](https://github.com/CodeShayk/FeatureOne/blob/v2.0.0/DeveloperGuide.md) |
61+
The following previous versions are available:
62+
63+
| Version | Release Notes |
64+
| ----------------------------------------------------------------| ----------------------------------------------------------------------|
65+
| [`v5.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v5.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v5.0.0) |
66+
| [`v4.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v4.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v4.0.0) |
67+
| [`v3.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v3.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v3.0.0) |
68+
| [`v2.0.0`](https://github.com/CodeShayk/FeatureOne/tree/v2.0.0) | [Notes](https://github.com/CodeShayk/FeatureOne/releases/tag/v2.0.0) |
69+
70+
## Recent Releases
71+
72+
| Version | Release Date | Type | Key Changes | Backward Compatibility |
73+
|--------|-------------|------|-------------|---------------------|
74+
| v5.0.0 | Previous | Initial | Core feature toggle functionality | N/A (Initial release) |
75+
| v5.1.0 | Nov 03, 2025 | Minor | **Security fixes** (ReDoS protection, secure type loading), **architectural improvements** (prefix matching, dependency injection), **new features** (DateRangeCondition, configuration validation), **DI integration** | High - maintains all existing functionality with minor security-related behavioral changes |
76+
6777
## Credits
6878
Thank you for reading. Please fork, explore, contribute and report. Happy Coding !! :)
6979

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using FeatureOne.Cache;
3+
using FeatureOne.File.StorageProvider;
4+
using FeatureOne.Json;
5+
using Microsoft.Extensions.DependencyInjection;
6+
7+
namespace FeatureOne.File.Extensions
8+
{
9+
/// <summary>
10+
/// Extension methods for adding FeatureOne services to the DI container
11+
/// </summary>
12+
public static class FeatureOneFileExtensions
13+
{
14+
/// <summary>
15+
/// Add Feature One with File storage.
16+
/// </summary>
17+
/// <param name="services"></param>
18+
/// <param name="configuration">Required: Configuration.</param>
19+
/// <param name="deserializer">Optional: Custom Deserializer for Toggles. Pass Null to use default.</param>
20+
/// <param name="cache">Optional: Custom Cache for Toggles. Pass Null to use default memCache.</param>
21+
/// <returns></returns>
22+
public static IServiceCollection AddFeatureOneWithFileStorage(this IServiceCollection services,
23+
FileConfiguration configuration, IToggleDeserializer deserializer = null, ICache cache = null)
24+
{
25+
if (configuration == null)
26+
throw new ArgumentNullException("FileConfiguration is required.");
27+
28+
return services
29+
.AddFeatureOne(provider =>
30+
new FileStorageProvider(configuration,
31+
new FileReader(configuration),
32+
deserializer ?? new ToggleDeserializer(new ConditionDeserializer()),
33+
cache ?? new FeatureCache()));
34+
}
35+
}
36+
}

src/FeatureOne.File/FeatureOne.File.csproj

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,29 @@
2121
<PackageReadmeFile>README.md</PackageReadmeFile>
2222
<RepositoryUrl>https://github.com/codeshayk/FeatureOne</RepositoryUrl>
2323
<RepositoryType>git</RepositoryType>
24-
<PackageTags>feature-toggle; feature-flag; feature-flags; feature-toggles; .net8.0; featureOne; File-system; File-Backend; File-Toggles;</PackageTags>
25-
<Version>5.0.1</Version>
24+
<PackageTags>feature-toggle; feature-flag; feature-flags; feature-toggles; featureOne; File-system; File-Backend; File-Toggles;</PackageTags>
25+
<Version>5.1.0</Version>
2626
<PackageLicenseFile>License.md</PackageLicenseFile>
2727
<PackageIcon>ninja-icon-16.png</PackageIcon>
2828
<PackageReleaseNotes>
29-
Release Notes v5.0.1. - Targets .Net Framework 4.6.2, .NetStandard 2.1 and .Net 9.0
29+
Release Notes v5.1.0. - Targets .Net Framework 4.6.2, .NetStandard 2.1 and .Net 9.0
3030
Library to Implement Feature Toggles to hide/show program features with File system storage.
31-
- Provides Out of box Simple and Regex toggle conditions.
32-
- Provides Out of box support for File system storage provider to store toggles on disk file.
33-
- Provides the support for default memory caching via configuration.
34-
- Provides extensibility for custom implementations ie.
31+
Security Fixes:
32+
- Fixed RegexCondition ReDoS (Regular Expression Denial of Service) vulnerability with timeout validation
33+
- Secured dynamic type loading in ConditionDeserializer with explicit safe type registry
34+
35+
Architectural Improvements:
36+
- Fixed FindStartsWith implementation for actual prefix matching
37+
- Implemented proper dependency injection patterns with null validation
38+
39+
New Features:
40+
- Added DateRangeCondition for time-based feature toggles
41+
- Added Configuration Validation System with clear error messages
42+
43+
Provides Out of box Simple and Regex toggle conditions.
44+
Provides Out of box support for File system storage provider to store toggles on disk file.
45+
Provides the support for default memory caching via configuration.
46+
Provides extensibility for custom implementations ie.
3547
-- Provides extensibility for implementing custom toggle conditions for bespoke use cases.
3648
-- Provides extensibility for implementing custom caching provider.
3749
-- Provides extensibility for implementing custom toggle deserializer for bespoke scenarios.
@@ -59,6 +71,7 @@
5971
</ItemGroup>
6072

6173
<ItemGroup>
74+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
6275
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
6376
</ItemGroup>
6477

src/FeatureOne.File/FileRecord.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
3-
41
namespace FeatureOne.File
52
{
63
public class FileRecord

src/FeatureOne.File/StorageProvider/FileReader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Threading;
53
using System.Security.Cryptography;
4+
using System.Text;
65
using System.Text.Json;
76
using System.Text.Json.Nodes;
7+
using System.Threading;
88

99
namespace FeatureOne.File.StorageProvider
1010
{
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using FeatureOne.Cache;
3+
using FeatureOne.Json;
4+
using FeatureOne.SQL.StorageProvider;
5+
using Microsoft.Extensions.DependencyInjection;
6+
7+
namespace FeatureOne.SQL.Extensions
8+
{
9+
/// <summary>
10+
/// Extension methods for adding FeatureOne services to the DI container
11+
/// </summary>
12+
public static class FeatureOneSQLExtensions
13+
{
14+
/// <summary>
15+
/// Add Feature One with SQL storage.
16+
/// </summary>
17+
/// <param name="services"></param>
18+
/// <param name="configuration">Required: SQL Configuration.</param>
19+
/// <param name="deserializer">Optional: Custom Deserializer for Toggles. Pass Null to use default.</param>
20+
/// <param name="cache">Optional: Custom Cache for Toggles. Pass Null to use default memCache.</param>
21+
/// <returns></returns>
22+
public static IServiceCollection AddFeatureOneWithSQLStorage(this IServiceCollection services,
23+
SQLConfiguration configuration, IToggleDeserializer deserializer = null, ICache cache = null)
24+
{
25+
if (configuration == null)
26+
throw new ArgumentNullException("SQLConfiguration is required.");
27+
28+
return services
29+
.AddFeatureOne(provider =>
30+
new SQLStorageProvider(repository: new DbRepository(configuration),
31+
deserializer: deserializer ?? new ToggleDeserializer(new ConditionDeserializer()),
32+
cache: cache ?? new FeatureCache(),
33+
cacheSettings: configuration.CacheSettings));
34+
}
35+
}
36+
}

src/FeatureOne.SQL/FeatureOne.SQL.csproj

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,29 @@
2222
<PackageReadmeFile>README.md</PackageReadmeFile>
2323
<RepositoryUrl>https://github.com/CodeShayk/FeatureOne</RepositoryUrl>
2424
<RepositoryType>git</RepositoryType>
25-
<PackageTags>feature-toggle; feature-flag; feature-flags; feature-toggles; .net8.0; featureOne; SQL-Backend; SQL-Toggles; SQL</PackageTags>
26-
<Version>5.0.1</Version>
25+
<PackageTags>feature-toggle; feature-flag; feature-flags; feature-toggles; featureOne; SQL-Backend; SQL-Toggles; SQL</PackageTags>
26+
<Version>5.1.0</Version>
2727
<PackageLicenseFile>License.md</PackageLicenseFile>
2828
<PackageIcon>ninja-icon-16.png</PackageIcon>
2929
<PackageReleaseNotes>
30-
Release Notes v5.0.1. - Targets .Net Framework 4.6.2, .NetStandard 2.1 and .Net 9.0
30+
Release Notes v5.1.0. - Targets .Net Framework 4.6.2, .NetStandard 2.1 and .Net 9.0
3131
Library to Implement Feature Toggles to hide/show program features with SQL storage.
32-
- Supports configuring all Db providers - MSSQL, SQLite, ODBC, OLEDB, MySQL, PostgreSQL.
33-
- Provides Out of box Simple and Regex toggle conditions.
34-
- Provides the support for default memory caching via configuration.
35-
- Provides extensibility for custom implementations ie.
32+
Security Fixes:
33+
- Fixed RegexCondition ReDoS (Regular Expression Denial of Service) vulnerability with timeout validation
34+
- Secured dynamic type loading in ConditionDeserializer with explicit safe type registry
35+
36+
Architectural Improvements:
37+
- Fixed FindStartsWith implementation for actual prefix matching
38+
- Implemented proper dependency injection patterns with null validation
39+
40+
New Features:
41+
- Added DateRangeCondition for time-based feature toggles
42+
- Added Configuration Validation System with clear error messages
43+
44+
Supports configuring all Db providers - MSSQL, SQLite, ODBC, OLEDB, MySQL, PostgreSQL.
45+
Provides Out of box Simple and Regex toggle conditions.
46+
Provides the support for default memory caching via configuration.
47+
Provides extensibility for custom implementations ie.
3648
-- Provides extensibility for implementing custom toggle conditions for bespoke use cases.
3749
-- Provides extensibility to plugin other SQL providers.
3850
-- Provides extensibility for implementing custom caching providers.
@@ -57,6 +69,7 @@
5769
</ItemGroup>
5870

5971
<ItemGroup>
72+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
6073
<PackageReference Include="System.Data.Common" Version="4.3.0" />
6174
<PackageReference Include="System.Text.Json" Version="9.0.0" />
6275
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />

src/FeatureOne/Cache/FeatureCache.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using System.Runtime.Caching;
32

43
namespace FeatureOne.Cache

src/FeatureOne/Core/Stores/FeatureStore.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@ public class FeatureStore : IFeatureStore
99
private readonly IStorageProvider storageProvider;
1010
private readonly IFeatureLogger logger;
1111

12-
public FeatureStore(IStorageProvider storageProvider) : this(storageProvider, new NullLogger())
12+
public FeatureStore(IStorageProvider storageProvider) : this(storageProvider, new DefaultLogger(null))
1313
{
1414
}
1515

1616
public FeatureStore(IStorageProvider storageProvider, IFeatureLogger logger)
1717
{
18-
this.storageProvider = storageProvider;
19-
this.logger = logger;
18+
this.storageProvider = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
19+
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
2020
}
2121

2222
public IEnumerable<IFeature> FindStartsWith(string name)
2323
{
2424
try
2525
{
26+
if (string.IsNullOrWhiteSpace(name))
27+
{
28+
logger?.Info($"FeatureOne, Action='StorageProvider.Get', Message='The provided feature name was null or whitespace.'");
29+
return Enumerable.Empty<IFeature>();
30+
}
31+
2632
var features = storageProvider.GetByName(name);
2733
if (features == null || !features.Any())
2834
{
@@ -32,7 +38,9 @@ public IEnumerable<IFeature> FindStartsWith(string name)
3238

3339
var result = new List<IFeature>();
3440

35-
foreach (var feature in features.Where(x => x.Toggle?.Conditions != null && x.Toggle.Conditions.Any()))
41+
foreach (var feature in features
42+
.Where(x => x.Toggle?.Conditions != null && x.Toggle.Conditions.Any())
43+
.Where(x => x.Name.Value.StartsWith(name, StringComparison.OrdinalIgnoreCase)))
3644
result.Add(feature);
3745

3846
return result;

0 commit comments

Comments
 (0)