diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index e0254ff8d..991baf5de 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -9,12 +9,12 @@ Please review our [code of conduct](CODE_OF_CONDUCT.md).
## Our Development Process
We use GitHub with a simple GitFlow inspired flow.
-All new features and/or fixes are merged into the `development` branch by creating a Pull Request.
+All new features and/or fixes are merged into the `main` branch by creating a Pull Request.
## Pull Requests
We actively welcome your pull requests.
-1. Fork the repo and create your branch from `development`
+1. Fork the repo and create your branch from `main`
2. If you've added code that should be tested, add tests (DO follow [Microsoft Engineering Guidelines](https://github.com/dotnet/aspnetcore/wiki/Engineering-guidelines))
3. Any changes or additions requires documentation in the form of documenting public members
4. Ensure that all existing as well as new test passes
diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml
index 8178ad0b7..f3042db65 100644
--- a/.github/workflows/pipelines.yml
+++ b/.github/workflows/pipelines.yml
@@ -1,6 +1,6 @@
name: Cuemon CI/CD Pipeline
on:
- pull_request:
+ pull_request_target:
branches: [main]
paths-ignore:
- .codecov/**
diff --git a/src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthenticationHandler.cs b/src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthenticationHandler.cs
index 1ae93c2ab..c4f357909 100644
--- a/src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthenticationHandler.cs
+++ b/src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthenticationHandler.cs
@@ -11,51 +11,63 @@
namespace Cuemon.AspNetCore.Authentication.Basic
{
- ///
- /// Provides a HTTP Basic Authentication implementation of for ASP.NET Core.
- ///
- ///
- public class BasicAuthenticationHandler : AuthenticationHandler
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The monitor for the options instance.
- /// The .
- /// The .
- /// The .
- public BasicAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
- {
- }
+ ///
+ /// Provides a HTTP Basic Authentication implementation of for ASP.NET Core.
+ ///
+ ///
+ public class BasicAuthenticationHandler : AuthenticationHandler
+ {
+#if NET6_0
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The monitor for the options instance.
+ /// The .
+ /// The .
+ /// The .
+ public BasicAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
+ {
+ }
+#else
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The monitor for the options instance.
+ /// The .
+ /// The .
+ public BasicAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
+ {
+ }
+#endif
- ///
- /// Handle authenticate as an asynchronous operation.
- ///
- /// A representing the asynchronous operation.
- protected override Task HandleAuthenticateAsync()
- {
- Context.Items.TryAdd(nameof(BasicAuthenticationOptions), Options);
+ ///
+ /// Handle authenticate as an asynchronous operation.
+ ///
+ /// A representing the asynchronous operation.
+ protected override Task HandleAuthenticateAsync()
+ {
+ Context.Items.TryAdd(nameof(BasicAuthenticationOptions), Options);
- if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, BasicAuthenticationMiddleware.AuthorizationHeaderParser, BasicAuthenticationMiddleware.TryAuthenticate, out var principal))
+ if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, BasicAuthenticationMiddleware.AuthorizationHeaderParser, BasicAuthenticationMiddleware.TryAuthenticate, out var principal))
{
var unathorized = new UnauthorizedException(Options.UnauthorizedMessage, principal.Failure);
- return Task.FromResult(AuthenticateResult.Fail(unathorized));
- }
+ return Task.FromResult(AuthenticateResult.Fail(unathorized));
+ }
+
+ var ticket = new AuthenticationTicket(principal.Result, BasicAuthorizationHeader.Scheme);
+ return Task.FromResult(AuthenticateResult.Success(ticket));
+ }
- var ticket = new AuthenticationTicket(principal.Result, BasicAuthorizationHeader.Scheme);
- return Task.FromResult(AuthenticateResult.Success(ticket));
- }
-
///
- /// Handle challenge as an asynchronous operation.
- ///
- /// The properties.
- /// A representing the asynchronous operation.
- protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
+ /// Handle challenge as an asynchronous operation.
+ ///
+ /// The properties.
+ /// A representing the asynchronous operation.
+ protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
{
AuthenticationHandlerFeature.Set(await HandleAuthenticateOnceSafeAsync().ConfigureAwait(false), Context); // so annoying that Microsoft does not propagate AuthenticateResult properly - other have noticed as well: https://github.com/dotnet/aspnetcore/issues/44100
- Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, string.Create(CultureInfo.InvariantCulture, $"{BasicAuthorizationHeader.Scheme} realm=\"{Options.Realm}\""));
+ Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, string.Create(CultureInfo.InvariantCulture, $"{BasicAuthorizationHeader.Scheme} realm=\"{Options.Realm}\""));
await base.HandleChallengeAsync(properties).ConfigureAwait(false);
}
- }
+ }
}
diff --git a/src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationHandler.cs b/src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationHandler.cs
index 5f88fd601..c5501981c 100644
--- a/src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationHandler.cs
+++ b/src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationHandler.cs
@@ -12,63 +12,77 @@
namespace Cuemon.AspNetCore.Authentication.Digest
{
- ///
- /// Provides a HTTP Digest Access Authentication implementation of for ASP.NET Core.
- ///
- ///
- public class DigestAuthenticationHandler : AuthenticationHandler
- {
- private readonly INonceTracker _nonceTracker;
+ ///
+ /// Provides a HTTP Digest Access Authentication implementation of for ASP.NET Core.
+ ///
+ ///
+ public class DigestAuthenticationHandler : AuthenticationHandler
+ {
+ private readonly INonceTracker _nonceTracker;
+#if NET6_0
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The monitor for the options instance.
+ /// The .
+ /// The .
+ /// The .
+ /// The dependency injected implementation of an .
+ public DigestAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, INonceTracker nonceTracker = null) : base(options, logger, encoder, clock)
+ {
+ _nonceTracker = nonceTracker;
+ }
+#else
///
/// Initializes a new instance of the class.
///
/// The monitor for the options instance.
/// The .
/// The .
- /// The .
/// The dependency injected implementation of an .
- public DigestAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, INonceTracker nonceTracker = null) : base(options, logger, encoder, clock)
+ public DigestAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, INonceTracker nonceTracker = null) : base(options, logger, encoder)
{
_nonceTracker = nonceTracker;
}
+#endif
- ///
- /// Handle authenticate as an asynchronous operation.
- ///
- /// A representing the asynchronous operation.
- protected override Task HandleAuthenticateAsync()
- {
- Context.Items.TryAdd(nameof(DigestAuthenticationOptions), Options);
- Context.Items.TryAdd(nameof(INonceTracker), _nonceTracker);
+ ///
+ /// Handle authenticate as an asynchronous operation.
+ ///
+ /// A representing the asynchronous operation.
+ protected override Task HandleAuthenticateAsync()
+ {
+ Context.Items.TryAdd(nameof(DigestAuthenticationOptions), Options);
+ Context.Items.TryAdd(nameof(INonceTracker), _nonceTracker);
- if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, DigestAuthenticationMiddleware.AuthorizationHeaderParser, DigestAuthenticationMiddleware.TryAuthenticate, out var principal))
- {
+ if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, DigestAuthenticationMiddleware.AuthorizationHeaderParser, DigestAuthenticationMiddleware.TryAuthenticate, out var principal))
+ {
var unathorized = new UnauthorizedException(Options.UnauthorizedMessage, principal.Failure);
- return Task.FromResult(AuthenticateResult.Fail(unathorized));
- }
+ return Task.FromResult(AuthenticateResult.Fail(unathorized));
+ }
- var ticket = new AuthenticationTicket(principal.Result, DigestAuthorizationHeader.Scheme);
- return Task.FromResult(AuthenticateResult.Success(ticket));
- }
-
- ///
- /// Handle challenge as an asynchronous operation.
- ///
- /// The properties.½
- /// A representing the asynchronous operation.
- /// qop is included and supported to be compliant with RFC 2617 (hence, this implementation cannot revert to reduced legacy RFC 2069 mode).
- protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
- {
- string etag = Response.Headers[HeaderNames.ETag];
- if (string.IsNullOrEmpty(etag)) { etag = "no-entity-tag"; }
- var opaqueGenerator = Options.OpaqueGenerator;
- var nonceSecret = Options.NonceSecret;
- var nonceGenerator = Options.NonceGenerator;
- var staleNonce = Context.Items[DigestFields.Stale] as string ?? "false";
+ var ticket = new AuthenticationTicket(principal.Result, DigestAuthorizationHeader.Scheme);
+ return Task.FromResult(AuthenticateResult.Success(ticket));
+ }
+
+ ///
+ /// Handle challenge as an asynchronous operation.
+ ///
+ /// The properties.½
+ /// A representing the asynchronous operation.
+ /// qop is included and supported to be compliant with RFC 2617 (hence, this implementation cannot revert to reduced legacy RFC 2069 mode).
+ protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
+ {
+ string etag = Response.Headers[HeaderNames.ETag];
+ if (string.IsNullOrEmpty(etag)) { etag = "no-entity-tag"; }
+ var opaqueGenerator = Options.OpaqueGenerator;
+ var nonceSecret = Options.NonceSecret;
+ var nonceGenerator = Options.NonceGenerator;
+ var staleNonce = Context.Items[DigestFields.Stale] as string ?? "false";
AuthenticationHandlerFeature.Set(await HandleAuthenticateOnceSafeAsync().ConfigureAwait(false), Context); // so annoying that Microsoft does not propagate AuthenticateResult properly - other have noticed as well: https://github.com/dotnet/aspnetcore/issues/44100
- Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, string.Create(CultureInfo.InvariantCulture, $"{DigestAuthorizationHeader.Scheme} realm=\"{Options.Realm}\", qop=\"auth, auth-int\", nonce=\"{nonceGenerator(DateTime.UtcNow, etag, nonceSecret())}\", opaque=\"{opaqueGenerator()}\", stale=\"{staleNonce}\", algorithm=\"{DigestAuthenticationMiddleware.ParseAlgorithm(Options.Algorithm)}\""));
+ Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, string.Create(CultureInfo.InvariantCulture, $"{DigestAuthorizationHeader.Scheme} realm=\"{Options.Realm}\", qop=\"auth, auth-int\", nonce=\"{nonceGenerator(DateTime.UtcNow, etag, nonceSecret())}\", opaque=\"{opaqueGenerator()}\", stale=\"{staleNonce}\", algorithm=\"{DigestAuthenticationMiddleware.ParseAlgorithm(Options.Algorithm)}\""));
await base.HandleChallengeAsync(properties).ConfigureAwait(false);
- }
- }
+ }
+ }
}
diff --git a/src/Cuemon.AspNetCore.Authentication/Hmac/HmacAuthenticationHandler.cs b/src/Cuemon.AspNetCore.Authentication/Hmac/HmacAuthenticationHandler.cs
index 46ac119b6..c9b84749a 100644
--- a/src/Cuemon.AspNetCore.Authentication/Hmac/HmacAuthenticationHandler.cs
+++ b/src/Cuemon.AspNetCore.Authentication/Hmac/HmacAuthenticationHandler.cs
@@ -10,12 +10,13 @@
namespace Cuemon.AspNetCore.Authentication.Hmac
{
- ///
- /// Provides a HTTP HMAC Authentication implementation of for ASP.NET Core.
- ///
- ///
- public class HmacAuthenticationHandler : AuthenticationHandler
- {
+ ///
+ /// Provides a HTTP HMAC Authentication implementation of for ASP.NET Core.
+ ///
+ ///
+ public class HmacAuthenticationHandler : AuthenticationHandler
+ {
+#if NET6_0
///
/// Initializes a new instance of the class.
///
@@ -26,35 +27,46 @@ public class HmacAuthenticationHandler : AuthenticationHandler options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
}
+#else
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The monitor for the options instance.
+ /// The .
+ /// The .
+ public HmacAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
+ {
+ }
+#endif
- ///
- /// Handle authenticate as an asynchronous operation.
- ///
- /// A representing the asynchronous operation.
- protected override Task HandleAuthenticateAsync()
- {
- Context.Items.TryAdd(nameof(HmacAuthenticationOptions), Options);
+ ///
+ /// Handle authenticate as an asynchronous operation.
+ ///
+ /// A representing the asynchronous operation.
+ protected override Task HandleAuthenticateAsync()
+ {
+ Context.Items.TryAdd(nameof(HmacAuthenticationOptions), Options);
- if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, HmacAuthenticationMiddleware.AuthorizationHeaderParser, HmacAuthenticationMiddleware.TryAuthenticate, out var principal))
- {
+ if (!Authenticator.TryAuthenticate(Context, Options.RequireSecureConnection, HmacAuthenticationMiddleware.AuthorizationHeaderParser, HmacAuthenticationMiddleware.TryAuthenticate, out var principal))
+ {
var unathorized = new UnauthorizedException(Options.UnauthorizedMessage, principal.Failure);
- return Task.FromResult(AuthenticateResult.Fail(unathorized));
- }
+ return Task.FromResult(AuthenticateResult.Fail(unathorized));
+ }
- var ticket = new AuthenticationTicket(principal.Result, Options.AuthenticationScheme);
- return Task.FromResult(AuthenticateResult.Success(ticket));
- }
+ var ticket = new AuthenticationTicket(principal.Result, Options.AuthenticationScheme);
+ return Task.FromResult(AuthenticateResult.Success(ticket));
+ }
- ///
- /// Handle challenge as an asynchronous operation.
- ///
- /// The properties.
- /// A representing the asynchronous operation.
- protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
- {
+ ///
+ /// Handle challenge as an asynchronous operation.
+ ///
+ /// The properties.
+ /// A representing the asynchronous operation.
+ protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
+ {
AuthenticationHandlerFeature.Set(await HandleAuthenticateOnceSafeAsync().ConfigureAwait(false), Context); // so annoying that Microsoft does not propagate AuthenticateResult properly - other have noticed as well: https://github.com/dotnet/aspnetcore/issues/44100
- Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, Options.AuthenticationScheme);
+ Decorator.Enclose(Response.Headers).TryAdd(HeaderNames.WWWAuthenticate, Options.AuthenticationScheme);
await base.HandleChallengeAsync(properties).ConfigureAwait(false);
- }
- }
+ }
+ }
}
diff --git a/src/Cuemon.AspNetCore.Mvc/GlobalSuppressions.cs b/src/Cuemon.AspNetCore.Mvc/GlobalSuppressions.cs
index 9b5d87846..ab7fb8d89 100644
--- a/src/Cuemon.AspNetCore.Mvc/GlobalSuppressions.cs
+++ b/src/Cuemon.AspNetCore.Mvc/GlobalSuppressions.cs
@@ -9,3 +9,4 @@
[assembly: SuppressMessage("Major Code Smell", "S1066:Collapsible \"if\" statements should be merged", Justification = "By design; easier for debug purposes and with clear scope.", Scope = "member", Target = "~M:Cuemon.AspNetCore.Mvc.Filters.Cacheable.HttpLastModifiedHeaderFilter.OnResultExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext,Microsoft.AspNetCore.Mvc.Filters.ResultExecutionDelegate)~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Major Code Smell", "S1066:Collapsible \"if\" statements should be merged", Justification = "By design; easier for debug purposes and with clear scope.", Scope = "member", Target = "~M:Cuemon.AspNetCore.Mvc.Filters.Cacheable.HttpEntityTagHeaderFilter.OnResultExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext,Microsoft.AspNetCore.Mvc.Filters.ResultExecutionDelegate)~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Critical Code Smell", "S3776:Cognitive Complexity of methods should not be too high", Justification = "If i invert the if-statement, the warning goes away - but the code becomes harder to read. So for now, i exclude it as 'by design'.", Scope = "member", Target = "~M:Cuemon.AspNetCore.Mvc.Filters.Diagnostics.FaultDescriptorFilter.OnException(Microsoft.AspNetCore.Mvc.Filters.ExceptionContext)")]
+[assembly: SuppressMessage("Minor Code Smell", "S3236:Caller information arguments should not be provided explicitly", Justification = "Intentional.", Scope = "member", Target = "~M:Cuemon.AspNetCore.Mvc.Filters.Diagnostics.FaultDescriptorFilter.#ctor(Microsoft.Extensions.Options.IOptions{Cuemon.AspNetCore.Mvc.Filters.Diagnostics.MvcFaultDescriptorOptions})")]
diff --git a/src/Cuemon.Core/Condition.cs b/src/Cuemon.Core/Condition.cs
index dd5274587..4151739f0 100644
--- a/src/Cuemon.Core/Condition.cs
+++ b/src/Cuemon.Core/Condition.cs
@@ -18,7 +18,7 @@ public sealed class Condition
private static readonly Condition ExtendedCondition = new();
private static readonly Regex RegExEmailAddressValidator = new(@"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|""(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])",
- RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
+ RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled, TimeSpan.FromSeconds(2));
///
/// Gets the singleton instance of the Condition functionality allowing for extensions methods like: Condition.Query.IsTrue().
diff --git a/src/Cuemon.Core/StringFactory.cs b/src/Cuemon.Core/StringFactory.cs
index 7046ffee5..4f9444f65 100644
--- a/src/Cuemon.Core/StringFactory.cs
+++ b/src/Cuemon.Core/StringFactory.cs
@@ -24,7 +24,11 @@ public static class StringFactory
public static string CreateHexadecimal(byte[] value)
{
Validator.ThrowIfNull(value);
+#if NET6_0_OR_GREATER
+ return Convert.ToHexString(value).Replace("-", "").ToLowerInvariant();
+#else
return BitConverter.ToString(value).Replace("-", "").ToLowerInvariant();
+#endif
}
///
diff --git a/src/Cuemon.Core/StringReplaceEngine.cs b/src/Cuemon.Core/StringReplaceEngine.cs
index 22658d4de..5bfe83304 100644
--- a/src/Cuemon.Core/StringReplaceEngine.cs
+++ b/src/Cuemon.Core/StringReplaceEngine.cs
@@ -56,7 +56,7 @@ private static string ToRegExPattern(IEnumerable replacePairs
private string RenderReplacement()
{
- var regex = new Regex(ToRegExPattern(ReplacePairs, out var lookupTable), ToRegExOptions(Comparison));
+ var regex = new Regex(ToRegExPattern(ReplacePairs, out var lookupTable), ToRegExOptions(Comparison), TimeSpan.FromSeconds(2));
var matches = regex.Matches(Value);
foreach (Match match in matches)
{
@@ -114,4 +114,4 @@ public override string ToString()
return RenderReplacement();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Cuemon.Core/Text/ParserFactory.cs b/src/Cuemon.Core/Text/ParserFactory.cs
index b40dcb013..f4f27f66d 100644
--- a/src/Cuemon.Core/Text/ParserFactory.cs
+++ b/src/Cuemon.Core/Text/ParserFactory.cs
@@ -408,7 +408,7 @@ public static IConfigurableParser FromPro
///
/// cannot be converted to the specified .
///
- /// If the underlying of is a , then this will be used in the conversion.
+ /// If the underlying of is a , then this will be used in the conversion.
public static IConfigurableParser FromObject()
{
return CreateConfigurableParser((input, targetType, setup) =>
diff --git a/src/Cuemon.Data/DataManager.cs b/src/Cuemon.Data/DataManager.cs
index 37456d68d..4213acf50 100644
--- a/src/Cuemon.Data/DataManager.cs
+++ b/src/Cuemon.Data/DataManager.cs
@@ -264,7 +264,7 @@ public virtual async Task