From 60f50fe5e77ec7f85f53ad4cd684993c123df880 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Fri, 23 Aug 2024 16:53:53 +0200 Subject: [PATCH 1/8] :pencil2: changed development -> main --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From b6e6282f9b929504b2acf11fe606e50eda85ed0e Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 16:18:26 +0200 Subject: [PATCH 2/8] :rotating_light: https://sonarcloud.io/organizations/geekle/rules?open=csharpsquid%3AS6444&rule_key=csharpsquid%3AS6444 paired with https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.-ctor?view=net-8.0#system-text-regularexpressions-regex-ctor(system-string-system-text-regularexpressions-regexoptions-system-timespan) --- src/Cuemon.Core/Condition.cs | 2 +- src/Cuemon.Core/StringReplaceEngine.cs | 4 ++-- src/Cuemon.Extensions.Core/StringExtensions.cs | 4 ++-- src/Cuemon.Extensions.Newtonsoft.Json/JData.cs | 2 +- src/Cuemon.Extensions.Xunit/Test.cs | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) 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/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.Extensions.Core/StringExtensions.cs b/src/Cuemon.Extensions.Core/StringExtensions.cs index fdc3bef5f..f8bb58021 100644 --- a/src/Cuemon.Extensions.Core/StringExtensions.cs +++ b/src/Cuemon.Extensions.Core/StringExtensions.cs @@ -442,7 +442,7 @@ public static string JsUnescape(this string value) { Validator.ThrowIfNull(value); var builder = new StringBuilder(value); - var unicode = new Regex("%u([0-9]|[a-f])([0-9]|[a-f])([0-9]|[a-f])([0-9]|[a-f])", RegexOptions.IgnoreCase); + var unicode = new Regex("%u([0-9]|[a-f])([0-9]|[a-f])([0-9]|[a-f])([0-9]|[a-f])", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(2)); var matches = unicode.Matches(value); foreach (Match unicodeMatch in matches) { @@ -941,4 +941,4 @@ public static string PrefixWith(this string source, string value) return new Stem(source).AttachPrefix(value); } } -} \ No newline at end of file +} diff --git a/src/Cuemon.Extensions.Newtonsoft.Json/JData.cs b/src/Cuemon.Extensions.Newtonsoft.Json/JData.cs index 675fa6501..07ee38483 100644 --- a/src/Cuemon.Extensions.Newtonsoft.Json/JData.cs +++ b/src/Cuemon.Extensions.Newtonsoft.Json/JData.cs @@ -145,7 +145,7 @@ private List FillHierarchy(JsonReader reader, JDataResult parent, F internal static class RegexExtensions { - internal static readonly Lazy LazySquareBracketsRemover = new(() => new Regex(@"\[[^]]*\]", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled)); + internal static readonly Lazy LazySquareBracketsRemover = new(() => new Regex(@"\[[^]]*\]", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled, TimeSpan.FromSeconds(2))); internal static string RemoveBrackets(this string path) { diff --git a/src/Cuemon.Extensions.Xunit/Test.cs b/src/Cuemon.Extensions.Xunit/Test.cs index c24ec2479..7266b8917 100644 --- a/src/Cuemon.Extensions.Xunit/Test.cs +++ b/src/Cuemon.Extensions.Xunit/Test.cs @@ -29,7 +29,7 @@ public static bool Match(string expected, string actual, Action var pattern = $"^{Regex.Escape(expected).Replace(options.SingleCharacter, ".").Replace(options.GroupOfCharacters, ".*")}$"; - if (Regex.IsMatch(actual, pattern)) { return true; } + if (Regex.IsMatch(actual, pattern, RegexOptions.None, TimeSpan.FromSeconds(2))) { return true; } var e = expected.Split(Environment.NewLine.ToCharArray()); var a = actual.Split(Environment.NewLine.ToCharArray()); @@ -76,4 +76,4 @@ protected override void OnDisposeManagedResources() { } } -} \ No newline at end of file +} From 084d55002c9ad576f1baa06c1b0d299b014847a4 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 16:28:32 +0200 Subject: [PATCH 3/8] :rotating_light: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1872 --- src/Cuemon.Core/StringFactory.cs | 4 ++++ 1 file changed, 4 insertions(+) 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 } /// From abf40dc74701fb271297aab4b88694c546156e09 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 16:37:29 +0200 Subject: [PATCH 4/8] :rotating_light: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0618 --- .../Basic/BasicAuthenticationHandler.cs | 86 +++++++++------- .../Digest/DigestAuthenticationHandler.cs | 98 +++++++++++-------- .../Hmac/HmacAuthenticationHandler.cs | 72 ++++++++------ 3 files changed, 147 insertions(+), 109 deletions(-) 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); - } - } + } + } } From ecc86595a2be9ece2e4832b4d9455475ca0d0c85 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 16:42:20 +0200 Subject: [PATCH 5/8] :rotating_light: https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs1574?f1url=%3FappId%3Droslyn%26k%3Dk(CS1574) --- src/Cuemon.Core/Text/ParserFactory.cs | 2 +- src/Cuemon.Data/DataManager.cs | 4 ++-- src/Cuemon.Extensions.Core/ObjectExtensions.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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 ExecuteScalarAsTypeAsync(DataStatement stateme /// /// The first column of the first row in the result set could not be converted. /// - /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . + /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . /// /// public virtual TResult ExecuteScalarAs(DataStatement statement, Action setup = null) @@ -285,7 +285,7 @@ public virtual TResult ExecuteScalarAs(DataStatement statement, Action< /// /// The first column of the first row in the result set could not be converted. /// - /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . + /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . /// /// public virtual async Task ExecuteScalarAsAsync(DataStatement statement, Action setup = null, CancellationToken ct = default) diff --git a/src/Cuemon.Extensions.Core/ObjectExtensions.cs b/src/Cuemon.Extensions.Core/ObjectExtensions.cs index 99bfec6b2..53bb7035a 100644 --- a/src/Cuemon.Extensions.Core/ObjectExtensions.cs +++ b/src/Cuemon.Extensions.Core/ObjectExtensions.cs @@ -83,7 +83,7 @@ public static TResult As(this T value, Func converter) /// /// could not be converted. /// - /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . + /// What differs from the is, that this converter supports generics and enums. Fallback uses and checks if the underlying of is a , then this will be used in the conversion together with . /// /// public static object As(this object value, Type targetType, Action setup = null) From a16ec88e79755d1a9eb77e098d0b67c7e0c67537 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 16:57:00 +0200 Subject: [PATCH 6/8] :rotating_light: https://sonarcloud.io/organizations/geekle/rules?open=csharpsquid%3AS3236&rule_key=csharpsquid%3AS3236 --- src/Cuemon.AspNetCore.Mvc/GlobalSuppressions.cs | 1 + src/Cuemon.Data/GlobalSuppressions.cs | 1 + 2 files changed, 2 insertions(+) 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.Data/GlobalSuppressions.cs b/src/Cuemon.Data/GlobalSuppressions.cs index be2c0d06d..a0b1fc0c9 100644 --- a/src/Cuemon.Data/GlobalSuppressions.cs +++ b/src/Cuemon.Data/GlobalSuppressions.cs @@ -10,3 +10,4 @@ [assembly: SuppressMessage("Major Bug", "S1751:Loops with at most one iteration should be refactored", Justification = "This is by design and how a reader is implemented. While there are lines to be read, we built a token, and the token is being read. When read, it returns true and proceeds to next line.", Scope = "member", Target = "~M:Cuemon.Data.DsvDataReader.ReadAsync~System.Threading.Tasks.Task{System.Boolean}")] [assembly: SuppressMessage("Major Code Smell", "S907:\"goto\" statement should not be used", Justification = "Legacy implementation.", Scope = "member", Target = "~M:Cuemon.Data.Xml.XmlDataReader.ReadNext(System.Boolean)~System.Boolean")] [assembly: SuppressMessage("Major Code Smell", "S1168:Empty arrays and collections should be returned instead of null", Justification = "By design. Not relevant in this context.", Scope = "member", Target = "~P:Cuemon.Data.DsvDataReader.NullRead")] +[assembly: SuppressMessage("Minor Code Smell", "S3236:Caller information arguments should not be provided explicitly", Justification = "Intentional.", Scope = "member", Target = "~M:Cuemon.Data.DataManager.OpenConnection(System.Data.IDbCommand)")] From fae2050d144c2c1a0feef2ec2e23d3d392fc4c2b Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sun, 25 Aug 2024 23:12:35 +0200 Subject: [PATCH 7/8] :rotating_light: remove code duplication --- src/Cuemon.IO/StreamFactory.cs | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/Cuemon.IO/StreamFactory.cs b/src/Cuemon.IO/StreamFactory.cs index ca67c271b..ad51bdbb7 100644 --- a/src/Cuemon.IO/StreamFactory.cs +++ b/src/Cuemon.IO/StreamFactory.cs @@ -222,31 +222,12 @@ public static Stream Create(Action, T1, private static Stream CreateBufferStreamCore(ActionFactory factory, Action setup = null) where TTuple : Template> { var options = Patterns.Configure(setup); - return Patterns.SafeInvoke(() => new MemoryStream(options.BufferSize), (ms, f) => + return CreateStreamCore>(factory, options, options.BufferSize, (f, ms) => { var writer = new ArrayBufferWriter(options.BufferSize); - f.GenericArguments.Arg1 = writer; f.ExecuteMethod(); - ms.Write(writer.WrittenSpan); - ms.Flush(); - ms.Position = 0; - if (options.Preamble == PreambleSequence.Remove) - { - var preamble = options.Encoding.GetPreamble(); - if (preamble.Length > 0) - { - return ByteOrderMark.Remove(ms, options.Encoding) as MemoryStream; - } - } - return ms; - }, factory, (ex, f) => - { - var parameters = new List(); - parameters.AddRange(f.GenericArguments.ToArray()); - parameters.Add(options); - throw ExceptionInsights.Embed(new InvalidOperationException("There is an error in the Stream being written.", ex), f.DelegateInfo, parameters.ToArray()); }); } @@ -255,13 +236,20 @@ private static Stream CreateBufferStreamCore(ActionFactory facto private static Stream CreateStreamCore(ActionFactory factory, Action setup = null) where TTuple : Template { var options = Patterns.Configure(setup); - return Patterns.SafeInvoke(() => new MemoryStream(options.BufferSize), (ms, f) => + return CreateStreamCore(factory, options, options.BufferSize, (f, ms) => { var writer = new InternalStreamWriter(ms, options); - f.GenericArguments.Arg1 = writer; f.ExecuteMethod(); writer.Flush(); + }); + } + + private static Stream CreateStreamCore(ActionFactory factory, StreamEncodingOptions options, int bufferSize, Action, MemoryStream> writerFactory) where TTuple : Template + { + return Patterns.SafeInvoke(() => new MemoryStream(bufferSize), (ms, f) => + { + writerFactory(f, ms); ms.Flush(); ms.Position = 0; From a49de19620c356160e554083dc11bd46aa463cdc Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Wed, 28 Aug 2024 22:16:46 +0200 Subject: [PATCH 8/8] :alembic: potential fix of fork gha exception; https://www.codu.co/articles/when-to-use-pull_request_target-instead-of-pull_request-in-github-actions-k3pao1qz --- .github/workflows/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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/**