Initial commit: scadaproj umbrella — sister-project index, auth component normalization (design + GAPS), and the built ZB.MOM.WW.Auth shared library (0.1.0, flattened in).
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ZB.MOM.WW.Auth.Abstractions.Ldap;
|
||||
using ZB.MOM.WW.Auth.AspNetCore;
|
||||
using ZB.MOM.WW.Auth.Ldap;
|
||||
|
||||
namespace ZB.MOM.WW.Auth.AspNetCore.Tests;
|
||||
|
||||
public class ServiceCollectionExtensionsTests
|
||||
{
|
||||
private const string LdapSection = "Auth:Ldap";
|
||||
|
||||
private const string LdapServer = "ldap.example.com";
|
||||
|
||||
private static IConfiguration BuildConfiguration() =>
|
||||
new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
[$"{LdapSection}:Server"] = LdapServer,
|
||||
[$"{LdapSection}:SearchBase"] = "dc=example,dc=com",
|
||||
[$"{LdapSection}:ServiceAccountDn"] = "cn=svc,dc=example,dc=com",
|
||||
[$"{LdapSection}:Transport"] = nameof(LdapTransport.Ldaps),
|
||||
})
|
||||
.Build();
|
||||
|
||||
[Fact]
|
||||
public void AddZbLdapAuth_ResolvesLdapAuthService()
|
||||
{
|
||||
IConfiguration config = BuildConfiguration();
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddZbLdapAuth(config, LdapSection);
|
||||
|
||||
using ServiceProvider provider = services.BuildServiceProvider();
|
||||
|
||||
var service = provider.GetRequiredService<ILdapAuthService>();
|
||||
|
||||
Assert.NotNull(service);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddZbLdapAuth_ILdapAuthService_IsSingleton()
|
||||
{
|
||||
IConfiguration config = BuildConfiguration();
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddZbLdapAuth(config, LdapSection);
|
||||
|
||||
using ServiceProvider provider = services.BuildServiceProvider();
|
||||
|
||||
var first = provider.GetRequiredService<ILdapAuthService>();
|
||||
var second = provider.GetRequiredService<ILdapAuthService>();
|
||||
|
||||
Assert.Same(first, second);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddZbLdapAuth_BindsOptionsFromSection()
|
||||
{
|
||||
IConfiguration config = BuildConfiguration();
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddZbLdapAuth(config, LdapSection);
|
||||
|
||||
using ServiceProvider provider = services.BuildServiceProvider();
|
||||
var options = provider.GetRequiredService<IOptions<LdapOptions>>();
|
||||
|
||||
Assert.Equal(LdapServer, options.Value.Server);
|
||||
Assert.Equal("dc=example,dc=com", options.Value.SearchBase);
|
||||
Assert.Equal(LdapTransport.Ldaps, options.Value.Transport);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddZbLdapAuth_RegistersOptionsValidator()
|
||||
{
|
||||
IConfiguration config = BuildConfiguration();
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddZbLdapAuth(config, LdapSection);
|
||||
|
||||
using ServiceProvider provider = services.BuildServiceProvider();
|
||||
|
||||
var validators = provider.GetServices<IValidateOptions<LdapOptions>>().ToList();
|
||||
|
||||
Assert.Contains(validators, v => v is LdapOptionsValidator);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Resolves CookieAuthenticationOptions, IServiceCollection, IConfiguration, and the
|
||||
in-memory configuration provider used by the DI/cookie tests. -->
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ZB.MOM.WW.Auth.AspNetCore\ZB.MOM.WW.Auth.AspNetCore.csproj" />
|
||||
<ProjectReference Include="..\..\src\ZB.MOM.WW.Auth.Abstractions\ZB.MOM.WW.Auth.Abstractions.csproj" />
|
||||
<!-- Referenced so the DI tests can assert the concrete LdapOptionsValidator registration. -->
|
||||
<ProjectReference Include="..\..\src\ZB.MOM.WW.Auth.Ldap\ZB.MOM.WW.Auth.Ldap.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Security.Claims;
|
||||
using ZB.MOM.WW.Auth.AspNetCore;
|
||||
|
||||
namespace ZB.MOM.WW.Auth.AspNetCore.Tests;
|
||||
|
||||
public class ZbClaimTypesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Name_AliasesClaimTypesName()
|
||||
{
|
||||
Assert.Equal(ClaimTypes.Name, ZbClaimTypes.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Role_AliasesClaimTypesRole()
|
||||
{
|
||||
Assert.Equal(ClaimTypes.Role, ZbClaimTypes.Role);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisplayName_HasExpectedLiteralValue()
|
||||
{
|
||||
Assert.Equal("zb:displayname", ZbClaimTypes.DisplayName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Username_HasExpectedLiteralValue()
|
||||
{
|
||||
Assert.Equal("zb:username", ZbClaimTypes.Username);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScopeId_HasExpectedLiteralValue()
|
||||
{
|
||||
Assert.Equal("zb:scopeid", ZbClaimTypes.ScopeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using ZB.MOM.WW.Auth.AspNetCore;
|
||||
|
||||
namespace ZB.MOM.WW.Auth.AspNetCore.Tests;
|
||||
|
||||
public class ZbCookieDefaultsTests
|
||||
{
|
||||
[Fact]
|
||||
public void Apply_SetsHardenedCookieFlags()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
|
||||
ZbCookieDefaults.Apply(options);
|
||||
|
||||
Assert.True(options.Cookie.HttpOnly);
|
||||
Assert.Equal(SameSiteMode.Strict, options.Cookie.SameSite);
|
||||
Assert.True(options.SlidingExpiration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_UsesSuppliedIdleTimeout()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
var idle = TimeSpan.FromMinutes(12);
|
||||
|
||||
ZbCookieDefaults.Apply(options, idleTimeout: idle);
|
||||
|
||||
Assert.Equal(idle, options.ExpireTimeSpan);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_DefaultsToDefaultIdleTimeout_WhenNotSupplied()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
|
||||
ZbCookieDefaults.Apply(options);
|
||||
|
||||
Assert.Equal(ZbCookieDefaults.DefaultIdleTimeout, options.ExpireTimeSpan);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_RequireHttpsTrue_SetsSecurePolicyAlways()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
|
||||
ZbCookieDefaults.Apply(options, requireHttps: true);
|
||||
|
||||
Assert.Equal(CookieSecurePolicy.Always, options.Cookie.SecurePolicy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_RequireHttpsFalse_SetsSecurePolicySameAsRequest()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
|
||||
ZbCookieDefaults.Apply(options, requireHttps: false);
|
||||
|
||||
Assert.Equal(CookieSecurePolicy.SameAsRequest, options.Cookie.SecurePolicy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_DefaultsRequireHttpsToAlways()
|
||||
{
|
||||
var options = new CookieAuthenticationOptions();
|
||||
|
||||
ZbCookieDefaults.Apply(options);
|
||||
|
||||
Assert.Equal(CookieSecurePolicy.Always, options.Cookie.SecurePolicy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Apply_NullOptions_Throws()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => ZbCookieDefaults.Apply(null!));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user