Skip to content

Commit 51c275e

Browse files
authored
V9.0.0/hotfix, housekeeping and dependency bump (#76)
* 🚨 fixed https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1861 * ⬆️ bump swashbuckle * 🚨 https://sonarcloud.io/organizations/geekle/rules?open=csharpsquid%3AS1066&rule_key=csharpsquid%3AS1066 * 🚨 exclude IDE0008 * 🔧 updated to include more analysis rules and enforce code style in build * 🚨 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0055 * 🔧 exclude CA1200 * 🚨 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0130 * 🚑 hotfix for ThrowIfDifferent and ThrowIfNotDifferent * 🚨 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1000 * 🚨 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005 * 🚨 updated ignore list * ⬆️ bump MinVer, Microsoft.NET.Test.Sdk and YamlDotNet * 👷 need to read up on pull_request vs pull_request_target. Problem for now is mentioned here: https://github.com/orgs/community/discussions/40659 * 🚑 fixed Compare(..) in EnumerableSizeComparer{T}
1 parent 450b22e commit 51c275e

File tree

285 files changed

+5675
-5445
lines changed

Some content is hidden

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

285 files changed

+5675
-5445
lines changed

.editorconfig

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,67 @@ dotnet_diagnostic.S3267.severity = none
3131
# This is a violation of Framework Design Guidelines.
3232
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1859
3333
[*.{cs,vb}]
34-
dotnet_diagnostic.CA1859.severity = none
34+
dotnet_diagnostic.CA1859.severity = none
35+
36+
# IDE0008: Use explicit type
37+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0007-ide0008
38+
[*.{cs,vb}]
39+
dotnet_diagnostic.IDE0008.severity = none
40+
41+
[*.{cs,vb}]
42+
indent_style = space
43+
indent_size = 4
44+
45+
[*.xml]
46+
indent_style = space
47+
indent_size = 2
48+
49+
# IDE0078: Use pattern matching
50+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0078
51+
[*.{cs,vb}]
52+
dotnet_diagnostic.IDE0078.severity = none
53+
54+
# IDE0290: Use primary constructor
55+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0290
56+
[*.{cs,vb}]
57+
dotnet_diagnostic.IDE0290.severity = none
58+
59+
# CA1200: Avoid using cref tags with a prefix
60+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1200
61+
[*.{cs,vb}]
62+
dotnet_diagnostic.CA1200.severity = none
63+
64+
# IDE0305: Use collection expression for fluent
65+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0305
66+
[*.{cs,vb}]
67+
dotnet_diagnostic.IDE0305.severity = none
68+
69+
# IDE0011: Add braces
70+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0011
71+
[*.{cs,vb}]
72+
dotnet_diagnostic.IDE0011.severity = none
73+
74+
# IDE0028: Use collection initializers or expressions
75+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0028
76+
[*.{cs,vb}]
77+
dotnet_diagnostic.IDE0028.severity = none
78+
79+
# IDE0039: Use collection expression for array
80+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0300
81+
[*.{cs,vb}]
82+
dotnet_diagnostic.IDE0300.severity = none
83+
84+
# IDE0031: Use collection expression for empty
85+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0301
86+
[*.{cs,vb}]
87+
dotnet_diagnostic.IDE0301.severity = none
88+
89+
# IDE0046: Use conditional expression for return
90+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0046
91+
[*.{cs,vb}]
92+
dotnet_diagnostic.IDE0046.severity = none
93+
94+
# IDE0047: Parentheses preferences
95+
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0047-ide0048
96+
[*.{cs,vb}]
97+
dotnet_diagnostic.IDE0047.severity = none

.github/workflows/pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Cuemon CI/CD Pipeline
22
on:
3-
pull_request_target:
3+
pull_request:
44
branches: [main]
55
paths-ignore:
66
- .codecov/**

Directory.Build.props

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@
3636
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)cuemon.snk</AssemblyOriginatorKeyFile>
3737
<EnableNETAnalyzers>true</EnableNETAnalyzers>
3838
<AnalysisLevel>latest</AnalysisLevel>
39-
<AnalysisMode>Minimum</AnalysisMode>
40-
<NoWarn>7035,IDE0305,S6618</NoWarn>
39+
<AnalysisMode>Recommended</AnalysisMode>
40+
<NoWarn>7035,S6618</NoWarn>
4141
<MinVerTagPrefix>v</MinVerTagPrefix>
42+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
4243
</PropertyGroup>
4344

4445
<ItemGroup Condition="'$(NuGetPackageRoot)' != ''">
@@ -47,7 +48,7 @@
4748

4849
<ItemGroup Condition="'$(IsTestProject)' == 'false'">
4950
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
50-
<PackageReference Include="MinVer" Version="5.0.0" PrivateAssets="all" />
51+
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="all" />
5152
<None Include="..\..\.nuget\icon.png" Pack="true" Visible="false" PackagePath="icon.png" />
5253
<None Include="..\..\.nuget\$(MSBuildProjectName)\README.md" Pack="true" PackagePath="\" />
5354
</ItemGroup>
@@ -73,7 +74,7 @@
7374
</PropertyGroup>
7475

7576
<ItemGroup Condition="'$(IsTestProject)' == 'true'">
76-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
77+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
7778
<PackageReference Include="Microsoft.TestPlatform.ObjectModel" Version="17.10.0" Condition="$(TargetFramework.StartsWith('net4')) AND '$(IsLinux)' == 'true'" />
7879
<PackageReference Include="xunit" Version="2.9.0" />
7980
<PackageReference Include="xunit.runner.console" Version="2.9.0" />

src/Cuemon.AspNetCore.Authentication/AuthenticationOptions.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public abstract class AuthenticationOptions : AuthenticationSchemeOptions, IVali
3838
/// </remarks>
3939
protected AuthenticationOptions()
4040
{
41-
UnauthorizedMessage = "The request has not been applied because it lacks valid authentication credentials for the target resource.";
41+
UnauthorizedMessage = "The request has not been applied because it lacks valid authentication credentials for the target resource.";
4242
ResponseHandler = () => new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(UnauthorizedMessage) };
4343
RequireSecureConnection = true;
4444
}
@@ -61,16 +61,16 @@ protected AuthenticationOptions()
6161
/// <value>The message of an unauthorized request.</value>
6262
public string UnauthorizedMessage { get; set; }
6363

64-
/// <summary>
65-
/// Determines whether the public read-write properties of this instance are in a valid state.
66-
/// </summary>
67-
/// <exception cref="InvalidOperationException">
68-
/// <seealso cref="UnauthorizedMessage"/> cannot be null.
69-
/// </exception>
70-
/// <remarks>This method is expected to throw exceptions when one or more conditions fails to be in a valid state.</remarks>
71-
public virtual void ValidateOptions()
64+
/// <summary>
65+
/// Determines whether the public read-write properties of this instance are in a valid state.
66+
/// </summary>
67+
/// <exception cref="InvalidOperationException">
68+
/// <seealso cref="UnauthorizedMessage"/> cannot be null.
69+
/// </exception>
70+
/// <remarks>This method is expected to throw exceptions when one or more conditions fails to be in a valid state.</remarks>
71+
public virtual void ValidateOptions()
7272
{
73-
Validator.ThrowIfInvalidState(UnauthorizedMessage == null);
73+
Validator.ThrowIfInvalidState(UnauthorizedMessage == null);
7474
}
7575
}
7676
}

src/Cuemon.AspNetCore.Authentication/AuthorizationHeader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public virtual AuthorizationHeader Parse(string authorizationHeader, Action<Auth
3737
Validator.ThrowIfNullOrWhitespace(authorizationHeader);
3838
Validator.ThrowIfFalse(() => authorizationHeader.StartsWith(AuthenticationScheme), nameof(authorizationHeader), $"Header did not start with {AuthenticationScheme}.");
3939
Validator.ThrowIfInvalidConfigurator(setup, out var options);
40-
40+
4141
var headerWithoutScheme = authorizationHeader.Remove(0, AuthenticationScheme.Length + 1);
4242
var credentials = DelimitedString.Split(headerWithoutScheme, o => o.Delimiter = options.CredentialsDelimiter).ToList();
4343

src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthenticationOptions.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,19 @@ public BasicAuthenticationOptions()
4545
/// <value>The realm that defines the protection space.</value>
4646
public string Realm { get; set; }
4747

48-
/// <summary>
49-
/// Determines whether the public read-write properties of this instance are in a valid state.
50-
/// </summary>
51-
/// <exception cref="InvalidOperationException">
52-
/// <seealso cref="Authenticator"/> cannot be null - or -
53-
/// <seealso cref="Realm"/> cannot be null, empty or consist only of white-space characters.
54-
/// </exception>
55-
/// <remarks>This method is expected to throw exceptions when one or more conditions fails to be in a valid state.</remarks>
56-
public override void ValidateOptions()
48+
/// <summary>
49+
/// Determines whether the public read-write properties of this instance are in a valid state.
50+
/// </summary>
51+
/// <exception cref="InvalidOperationException">
52+
/// <seealso cref="Authenticator"/> cannot be null - or -
53+
/// <seealso cref="Realm"/> cannot be null, empty or consist only of white-space characters.
54+
/// </exception>
55+
/// <remarks>This method is expected to throw exceptions when one or more conditions fails to be in a valid state.</remarks>
56+
public override void ValidateOptions()
5757
{
5858
Validator.ThrowIfInvalidState(Authenticator == null);
5959
Validator.ThrowIfInvalidState(string.IsNullOrWhiteSpace(Realm));
60-
base.ValidateOptions();
60+
base.ValidateOptions();
6161
}
6262
}
6363
}

src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthorizationHeader.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,15 @@ public BasicAuthorizationHeader(string username, string password) : base(Scheme)
7575
/// <value>The password of the credentials.</value>
7676
public string Password { get; }
7777

78+
private static readonly char[] ColonSeparator = new[] { ':' };
79+
7880
/// <summary>
7981
/// Returns a <see cref="string" /> that represents this instance.
8082
/// </summary>
8183
/// <returns>A <see cref="string" /> that represents this instance.</returns>
8284
public override string ToString()
8385
{
84-
var credentials = Convert.ToBase64String(Decorator.Enclose($"{UserName}:{Password}").ToByteArray());
86+
var credentials = Convert.ToBase64String(Decorator.Enclose($"{UserName}:{Password}").ToByteArray());
8587
return $"{AuthenticationScheme} {credentials}";
8688
}
8789

@@ -117,7 +119,7 @@ protected override AuthorizationHeader ParseCore(IReadOnlyDictionary<string, str
117119
{
118120
options.Encoding = Encoding.ASCII;
119121
options.Preamble = PreambleSequence.Remove;
120-
}).Split(new [] { ':' }, 2);
122+
}).Split(ColonSeparator, 2);
121123

122124
if (plainCredentials.Length == 2 &&
123125
!string.IsNullOrWhiteSpace(plainCredentials[0]) &&
@@ -129,4 +131,4 @@ protected override AuthorizationHeader ParseCore(IReadOnlyDictionary<string, str
129131
return null;
130132
}
131133
}
132-
}
134+
}

src/Cuemon.AspNetCore.Authentication/Basic/BasicAuthorizationHeaderBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ public BasicAuthorizationHeaderBuilder AddPassword(string password)
3434
{
3535
return AddOrUpdate(BasicFields.Password, password);
3636
}
37-
37+
3838
/// <summary>
3939
/// Builds an instance of <see cref="BasicAuthorizationHeader"/> that implements <see cref="AuthorizationHeader" />.
4040
/// </summary>
4141
/// <returns>An instance of <see cref="BasicAuthorizationHeader"/>.</returns>
4242
public override BasicAuthorizationHeader Build()
4343
{
4444
ValidateData(BasicFields.UserName, BasicFields.Password);
45-
return new BasicAuthorizationHeader(Data[BasicFields.UserName], Data[BasicFields.Password]);
45+
return new BasicAuthorizationHeader(Data[BasicFields.UserName], Data[BasicFields.Password]);
4646
}
4747
}
4848
}

src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationHandler.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ public DigestAuthenticationHandler(IOptionsMonitor<DigestAuthenticationOptions>
3434
_nonceTracker = nonceTracker;
3535
}
3636
#else
37-
/// <summary>
38-
/// Initializes a new instance of the <see cref="DigestAuthenticationHandler"/> class.
39-
/// </summary>
40-
/// <param name="options">The monitor for the options instance.</param>
41-
/// <param name="logger">The <see cref="T:Microsoft.Extensions.Logging.ILoggerFactory" />.</param>
42-
/// <param name="encoder">The <see cref="T:System.Text.Encodings.Web.UrlEncoder" />.</param>
43-
/// <param name="nonceTracker">The dependency injected implementation of an <see cref="INonceTracker"/>.</param>
44-
public DigestAuthenticationHandler(IOptionsMonitor<DigestAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, INonceTracker nonceTracker = null) : base(options, logger, encoder)
45-
{
46-
_nonceTracker = nonceTracker;
47-
}
37+
/// <summary>
38+
/// Initializes a new instance of the <see cref="DigestAuthenticationHandler"/> class.
39+
/// </summary>
40+
/// <param name="options">The monitor for the options instance.</param>
41+
/// <param name="logger">The <see cref="T:Microsoft.Extensions.Logging.ILoggerFactory" />.</param>
42+
/// <param name="encoder">The <see cref="T:System.Text.Encodings.Web.UrlEncoder" />.</param>
43+
/// <param name="nonceTracker">The dependency injected implementation of an <see cref="INonceTracker"/>.</param>
44+
public DigestAuthenticationHandler(IOptionsMonitor<DigestAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, INonceTracker nonceTracker = null) : base(options, logger, encoder)
45+
{
46+
_nonceTracker = nonceTracker;
47+
}
4848
#endif
4949

5050
/// <summary>

src/Cuemon.AspNetCore.Authentication/Digest/DigestAuthenticationMiddleware.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ public DigestAuthenticationMiddleware(RequestDelegate next, Action<DigestAuthent
4646
/// <remarks><c>qop</c> is included and supported to be compliant with RFC 2617 (hence, this implementation cannot revert to reduced legacy RFC 2069 mode).</remarks>
4747
public override async Task InvokeAsync(HttpContext context, INonceTracker di)
4848
{
49-
if (Options.Authenticator == null) { throw new InvalidOperationException(string.Create(CultureInfo.InvariantCulture, $"The {nameof(Options.Authenticator)} delegate cannot be null.")); }
50-
51-
context.Items.TryAdd(nameof(DigestAuthenticationOptions), Options);
52-
context.Items.TryAdd(nameof(INonceTracker), di);
49+
if (Options.Authenticator == null) { throw new InvalidOperationException(string.Create(CultureInfo.InvariantCulture, $"The {nameof(Options.Authenticator)} delegate cannot be null.")); }
5350

54-
if (!Authenticator.TryAuthenticate(context, Options.RequireSecureConnection, AuthorizationHeaderParser, TryAuthenticate, out var principal))
51+
context.Items.TryAdd(nameof(DigestAuthenticationOptions), Options);
52+
context.Items.TryAdd(nameof(INonceTracker), di);
53+
54+
if (!Authenticator.TryAuthenticate(context, Options.RequireSecureConnection, AuthorizationHeaderParser, TryAuthenticate, out var principal))
5555
{
5656
await Decorator.Enclose(context).InvokeUnauthorizedExceptionAsync(Options, principal.Failure, dc =>
5757
{
@@ -66,18 +66,18 @@ await Decorator.Enclose(context).InvokeUnauthorizedExceptionAsync(Options, princ
6666
}
6767

6868
context.User = principal.Result;
69-
await Next.Invoke(context).ConfigureAwait(false);
69+
await Next.Invoke(context).ConfigureAwait(false);
7070
}
7171

7272
internal static bool TryAuthenticate(HttpContext context, DigestAuthorizationHeader header, out ConditionalValue<ClaimsPrincipal> result)
7373
{
74-
var options = context.Items[nameof(DigestAuthenticationOptions)] as DigestAuthenticationOptions;
74+
var options = context.Items[nameof(DigestAuthenticationOptions)] as DigestAuthenticationOptions;
7575
var nonceTracker = context.Items[nameof(INonceTracker)] as INonceTracker;
76-
if (options?.Authenticator == null)
77-
{
76+
if (options?.Authenticator == null)
77+
{
7878
result = new UnsuccessfulValue<ClaimsPrincipal>(new SecurityException($"{nameof(options.Authenticator)} was unexpectedly set to null."));
79-
return false;
80-
}
79+
return false;
80+
}
8181

8282
if (header == null)
8383
{

0 commit comments

Comments
 (0)