diff --git a/identity-server/hosts/Configuration/Host.Configuration.csproj b/identity-server/hosts/Configuration/Host.Configuration.csproj
index 3228ed659..bf309ccf7 100644
--- a/identity-server/hosts/Configuration/Host.Configuration.csproj
+++ b/identity-server/hosts/Configuration/Host.Configuration.csproj
@@ -19,10 +19,7 @@
-
-
-
@@ -30,7 +27,6 @@
-
diff --git a/identity-server/hosts/EntityFramework-dotnet9/IdentityServerExtensions.cs b/identity-server/hosts/EntityFramework-dotnet9/IdentityServerExtensions.cs
index d4f82b3e2..648d450c8 100644
--- a/identity-server/hosts/EntityFramework-dotnet9/IdentityServerExtensions.cs
+++ b/identity-server/hosts/EntityFramework-dotnet9/IdentityServerExtensions.cs
@@ -68,7 +68,6 @@ internal static WebApplicationBuilder ConfigureIdentityServer(this WebApplicatio
})
.AddAppAuthRedirectUriValidator()
.AddServerSideSessions()
- .AddScopeParser()
// this is something you will want in production to reduce load on and requests to the DB
//.AddConfigurationStoreCache()
@@ -82,21 +81,6 @@ internal static WebApplicationBuilder ConfigureIdentityServer(this WebApplicatio
.AddCustomTokenRequestValidator()
.AddScopeParser()
.AddMutualTlsSecretValidators()
-
- // Comment out `AddInMemoryOidcProviders` if you want to use the seeded identity providers
- .AddInMemoryOidcProviders(
- [
- new Duende.IdentityServer.Models.OidcProvider
- {
- Scheme = "dynamicprovider-idsvr",
- DisplayName = "IdentityServer (via Dynamic Providers)",
- Authority = "https://demo.duendesoftware.com",
- ClientId = "login",
- ResponseType = "id_token",
- Scope = "openid profile"
- }
- ])
-
.AddLicenseSummary();
builder.Services.AddDistributedMemoryCache();
diff --git a/identity-server/hosts/EntityFramework/IdentityServerExtensions.cs b/identity-server/hosts/EntityFramework/IdentityServerExtensions.cs
index f5d75e388..9fed14c7c 100644
--- a/identity-server/hosts/EntityFramework/IdentityServerExtensions.cs
+++ b/identity-server/hosts/EntityFramework/IdentityServerExtensions.cs
@@ -67,7 +67,6 @@ internal static WebApplicationBuilder ConfigureIdentityServer(this WebApplicatio
})
.AddAppAuthRedirectUriValidator()
.AddServerSideSessions()
- .AddScopeParser()
// this is something you will want in production to reduce load on and requests to the DB
//.AddConfigurationStoreCache()
@@ -81,18 +80,6 @@ internal static WebApplicationBuilder ConfigureIdentityServer(this WebApplicatio
.AddCustomTokenRequestValidator()
.AddScopeParser()
.AddMutualTlsSecretValidators()
- .AddInMemoryOidcProviders(
- [
- new Duende.IdentityServer.Models.OidcProvider
- {
- Scheme = "dynamicprovider-idsvr",
- DisplayName = "IdentityServer (via Dynamic Providers)",
- Authority = "https://demo.duendesoftware.com",
- ClientId = "login",
- ResponseType = "id_token",
- Scope = "openid profile"
- }
- ])
.AddLicenseSummary();
builder.Services.AddDistributedMemoryCache();
diff --git a/identity-server/hosts/Shared/Customization/ParameterizedScopeParser.cs b/identity-server/hosts/Shared/Customization/ParameterizedScopeParser.cs
index 5993fd615..f076a584d 100644
--- a/identity-server/hosts/Shared/Customization/ParameterizedScopeParser.cs
+++ b/identity-server/hosts/Shared/Customization/ParameterizedScopeParser.cs
@@ -36,7 +36,7 @@ public override void ParseScopeValue(ParseScopeContext scopeContext)
}
else
{
- // we get in here with a scope exactly "transaction", which is to say we're ignoring it
+ // we get in here with a scope exactly "transaction", which is to say we're ignoring it
// and not including it in the results
scopeContext.SetIgnore();
}
diff --git a/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationDetails.cs b/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationDetails.cs
new file mode 100644
index 000000000..137bb36c4
--- /dev/null
+++ b/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationDetails.cs
@@ -0,0 +1,6 @@
+// Copyright (c) Duende Software. All rights reserved.
+// See LICENSE in the project root for license information.
+
+namespace Duende.IdentityServer.Licensing.V2.Diagnostics.DiagnosticEntries;
+
+internal record RegisteredImplementationDetails(Type TInterface, List TDefaultImplementations);
diff --git a/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationsDiagnosticEntry.cs b/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationsDiagnosticEntry.cs
index 911b4b04d..97ddf74f7 100644
--- a/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationsDiagnosticEntry.cs
+++ b/identity-server/src/IdentityServer/Licensing/V2/Diagnostics/DiagnosticEntries/RegisteredImplementationsDiagnosticEntry.cs
@@ -2,12 +2,16 @@
// See LICENSE in the project root for license information.
using System.Text.Json;
+using Duende.IdentityServer.Events;
using Duende.IdentityServer.Hosting;
+using Duende.IdentityServer.Hosting.DynamicProviders;
using Duende.IdentityServer.Internal;
using Duende.IdentityServer.ResponseHandling;
using Duende.IdentityServer.Services;
+using Duende.IdentityServer.Services.Default;
using Duende.IdentityServer.Services.KeyManagement;
using Duende.IdentityServer.Stores;
+using Duende.IdentityServer.Stores.Empty;
using Duende.IdentityServer.Stores.Serialization;
using Duende.IdentityServer.Validation;
@@ -16,139 +20,142 @@ namespace Duende.IdentityServer.Licensing.V2.Diagnostics.DiagnosticEntries;
internal class RegisteredImplementationsDiagnosticEntry(ServiceCollectionAccessor serviceCollectionAccessor)
: IDiagnosticEntry
{
- private readonly Dictionary> _typesToInspect = new()
+ private readonly Dictionary> _typesToInspect = new()
{
{
- "Root", [ typeof(IIdentityServerTools) ]
+ "Root", [new (typeof(IIdentityServerTools), [typeof(IdentityServerTools)])]
},
{
"Hosting", [
- typeof(IEndpointHandler),
- typeof(IEndpointResult),
- typeof(IEndpointRouter),
- typeof(IHttpResponseWriter<>)
+ new (typeof(IEndpointHandler), []),
+ new (typeof(IEndpointResult), []),
+ new (typeof(IEndpointRouter), [typeof(EndpointRouter)]),
+ new (typeof(IHttpResponseWriter<>), []),
]
},
{
- "Infrastructure", [typeof(IClock), typeof(IConcurrencyLock<>)]
+ "Infrastructure", [
+ new(typeof(IClock), [typeof(DefaultClock)]),
+ new(typeof(IConcurrencyLock<>), [typeof(DefaultConcurrencyLock<>)]),
+ ]
},
{
"ResponseHandling", [
- typeof(IAuthorizeInteractionResponseGenerator),
- typeof(IAuthorizeResponseGenerator),
- typeof(IBackchannelAuthenticationResponseGenerator),
- typeof(IDeviceAuthorizationResponseGenerator),
- typeof(IDiscoveryResponseGenerator),
- typeof(IIntrospectionResponseGenerator),
- typeof(IPushedAuthorizationResponseGenerator),
- typeof(ITokenResponseGenerator),
- typeof(ITokenRevocationResponseGenerator),
- typeof(IUserInfoResponseGenerator)
+ new(typeof(IAuthorizeInteractionResponseGenerator), [typeof(AuthorizeInteractionResponseGenerator)]),
+ new(typeof(IAuthorizeResponseGenerator), [typeof(AuthorizeResponseGenerator)]),
+ new(typeof(IBackchannelAuthenticationResponseGenerator), [typeof(BackchannelAuthenticationResponseGenerator)]),
+ new(typeof(IDeviceAuthorizationResponseGenerator), [typeof(DeviceAuthorizationResponseGenerator)]),
+ new(typeof(IDiscoveryResponseGenerator), [typeof(DiscoveryResponseGenerator)]),
+ new(typeof(IIntrospectionResponseGenerator), [typeof(IntrospectionResponseGenerator)]),
+ new(typeof(IPushedAuthorizationResponseGenerator), [typeof(PushedAuthorizationResponseGenerator)]),
+ new(typeof(ITokenResponseGenerator), [typeof(TokenResponseGenerator)]),
+ new(typeof(ITokenRevocationResponseGenerator), [typeof(TokenRevocationResponseGenerator)]),
+ new(typeof(IUserInfoResponseGenerator), [typeof(UserInfoResponseGenerator)]),
]
},
{
"Services", [
- typeof(IAutomaticKeyManagerKeyStore),
- typeof(IBackchannelAuthenticationInteractionService),
- typeof(IBackchannelAuthenticationThrottlingService),
- typeof(IBackchannelAuthenticationUserNotificationService),
- typeof(IBackChannelLogoutHttpClient),
- typeof(IBackChannelLogoutService),
- typeof(ICache<>),
- typeof(ICancellationTokenProvider),
- typeof(IClaimsService),
- typeof(IConsentService),
- typeof(ICorsPolicyService),
- typeof(IDeviceFlowCodeService),
- typeof(IDeviceFlowInteractionService),
- typeof(IDeviceFlowThrottlingService),
- typeof(IEventService),
- typeof(IEventSink),
- typeof(IHandleGenerationService),
- typeof(IIdentityServerInteractionService),
- typeof(IIssuerNameService),
- typeof(IJwtRequestUriHttpClient),
- typeof(IKeyManager),
- typeof(IKeyMaterialService),
- typeof(ILogoutNotificationService),
- typeof(IPersistedGrantService),
- typeof(IProfileService),
- typeof(IPushedAuthorizationSerializer),
- typeof(IPushedAuthorizationService),
- typeof(IRefreshTokenService),
- typeof(IReplayCache),
- typeof(IReturnUrlParser),
- typeof(IServerUrls),
- typeof(ISessionCoordinationService),
- typeof(ISessionManagementService),
- typeof(ISigningKeyProtector),
- typeof(ISigningKeyStoreCache),
- typeof(ITokenCreationService),
- typeof(ITokenService),
- typeof(IUserCodeGenerator),
- typeof(IUserCodeService),
- typeof(IUserSession)
+ new(typeof(IAutomaticKeyManagerKeyStore), [typeof(AutomaticKeyManagerKeyStore)]),
+ new(typeof(IBackchannelAuthenticationInteractionService), [typeof(DefaultBackchannelAuthenticationInteractionService)]),
+ new(typeof(IBackchannelAuthenticationThrottlingService), [typeof(DistributedBackchannelAuthenticationThrottlingService)]),
+ new(typeof(IBackchannelAuthenticationUserNotificationService), [typeof(NopBackchannelAuthenticationUserNotificationService)]),
+ new(typeof(IBackChannelLogoutHttpClient), [typeof(DefaultBackChannelLogoutHttpClient)]),
+ new(typeof(IBackChannelLogoutService), [typeof(DefaultBackChannelLogoutService)]),
+ new(typeof(ICache<>), [typeof(DefaultCache<>)]),
+ new(typeof(ICancellationTokenProvider), [typeof(DefaultCancellationTokenProvider)]),
+ new(typeof(IClaimsService), [typeof(DefaultClaimsService)]),
+ new(typeof(IConsentService), [typeof(DefaultConsentService)]),
+ new(typeof(ICorsPolicyService), [typeof(DefaultCorsPolicyService)]),
+ new(typeof(IDeviceFlowCodeService), [typeof(DefaultDeviceFlowCodeService)]),
+ new(typeof(IDeviceFlowInteractionService), [typeof(DefaultDeviceFlowInteractionService)]),
+ new(typeof(IDeviceFlowThrottlingService), [typeof(DistributedDeviceFlowThrottlingService)]),
+ new(typeof(IEventService), [typeof(DefaultEventService)]),
+ new(typeof(IEventSink), [typeof(DefaultEventSink)]),
+ new(typeof(IHandleGenerationService), [typeof(DefaultHandleGenerationService)]),
+ new(typeof(IIdentityServerInteractionService), [typeof(DefaultIdentityServerInteractionService)]),
+ new(typeof(IIssuerNameService), [typeof(DefaultIssuerNameService)]),
+ new(typeof(IJwtRequestUriHttpClient), [typeof(DefaultJwtRequestUriHttpClient)]),
+ new(typeof(IKeyManager), [typeof(KeyManager)]),
+ new(typeof(IKeyMaterialService), [typeof(DefaultKeyMaterialService)]),
+ new(typeof(ILogoutNotificationService), [typeof(LogoutNotificationService)]),
+ new(typeof(IPersistedGrantService), [typeof(DefaultPersistedGrantService)]),
+ new(typeof(IProfileService), [typeof(DefaultProfileService)]),
+ new(typeof(IPushedAuthorizationSerializer), [typeof(PushedAuthorizationSerializer)]),
+ new(typeof(IPushedAuthorizationService), [typeof(PushedAuthorizationService)]),
+ new(typeof(IRefreshTokenService), [typeof(DefaultRefreshTokenService)]),
+ new(typeof(IReplayCache), [typeof(DefaultReplayCache)]),
+ new(typeof(IReturnUrlParser), [typeof(OidcReturnUrlParser)]),
+ new(typeof(IServerUrls), [typeof(DefaultServerUrls)]),
+ new(typeof(ISessionCoordinationService), [typeof(DefaultSessionCoordinationService)]),
+ new(typeof(ISessionManagementService), []),
+ new(typeof(ISigningKeyProtector), [typeof(DataProtectionKeyProtector)]),
+ new(typeof(ISigningKeyStoreCache), [typeof(InMemoryKeyStoreCache)]),
+ new(typeof(ITokenCreationService), [typeof(DefaultTokenCreationService)]),
+ new(typeof(ITokenService), [typeof(DefaultTokenService)]),
+ new(typeof(IUserCodeGenerator), [typeof(NumericUserCodeGenerator)]),
+ new(typeof(IUserCodeService), [typeof(DefaultUserCodeService)]),
+ new(typeof(IUserSession), [typeof(DefaultUserSession)]),
]
},
{
"Stores", [
- typeof(IAuthorizationCodeStore),
- typeof(IAuthorizationParametersMessageStore),
- typeof(IBackChannelAuthenticationRequestStore),
- typeof(IClientStore),
- typeof(IConsentMessageStore),
- typeof(IDeviceFlowStore),
- typeof(IIdentityProviderStore),
- typeof(IMessageStore<>),
- typeof(IPersistentGrantSerializer),
- typeof(IPersistedGrantStore),
- typeof(IPushedAuthorizationRequestStore),
- typeof(IReferenceTokenStore),
- typeof(IRefreshTokenStore),
- typeof(IResourceStore),
- typeof(IServerSideSessionsMarker),
- typeof(IServerSideSessionStore),
- typeof(IServerSideTicketStore),
- typeof(ISigningCredentialStore),
- typeof(ISigningKeyStore),
- typeof(IUserConsentStore),
- typeof(IValidationKeysStore)
+ new(typeof(IAuthorizationCodeStore), [typeof(DefaultAuthorizationCodeStore)]),
+ new(typeof(IAuthorizationParametersMessageStore), []),
+ new(typeof(IBackChannelAuthenticationRequestStore), [typeof(DefaultBackChannelAuthenticationRequestStore)]),
+ new(typeof(IClientStore), [typeof(EmptyClientStore)]),
+ new(typeof(IConsentMessageStore), [typeof(ConsentMessageStore)]),
+ new(typeof(IDeviceFlowStore), []),
+ new(typeof(IIdentityProviderStore), [typeof(NopIdentityProviderStore)]),
+ new(typeof(IMessageStore<>), [typeof(ProtectedDataMessageStore<>)]),
+ new(typeof(IPersistentGrantSerializer), [typeof(PersistentGrantSerializer)]),
+ new(typeof(IPersistedGrantStore), [typeof(InMemoryPersistedGrantStore)]),
+ new(typeof(IPushedAuthorizationRequestStore), [typeof(InMemoryPushedAuthorizationRequestStore)]),
+ new(typeof(IReferenceTokenStore), [typeof(DefaultReferenceTokenStore)]),
+ new(typeof(IRefreshTokenStore), [typeof(DefaultRefreshTokenStore)]),
+ new(typeof(IResourceStore), [typeof(EmptyResourceStore)]),
+ new(typeof(IServerSideSessionsMarker), []),
+ new(typeof(IServerSideSessionStore),[]),
+ new(typeof(IServerSideTicketStore),[]),
+ new(typeof(ISigningCredentialStore), []),
+ new(typeof(ISigningKeyStore), [typeof(FileSystemKeyStore)]),
+ new(typeof(IUserConsentStore), [typeof(DefaultUserConsentStore)]),
+ new(typeof(IValidationKeysStore), []),
]
},
{
"Validation", [
- typeof(IApiSecretValidator),
- typeof(IAuthorizeRequestValidator),
- typeof(IBackchannelAuthenticationRequestIdValidator),
- typeof(IBackchannelAuthenticationRequestValidator),
- typeof(IBackchannelAuthenticationUserValidator),
- typeof(IClientConfigurationValidator),
- typeof(IClientSecretValidator),
- typeof(ICustomAuthorizeRequestValidator),
- typeof(ICustomBackchannelAuthenticationValidator),
- typeof(ICustomTokenRequestValidator),
- typeof(ICustomTokenValidator),
- typeof(IDeviceAuthorizationRequestValidator),
- typeof(IDeviceCodeValidator),
- typeof(IDPoPProofValidator),
- typeof(IEndSessionRequestValidator),
- typeof(IExtensionGrantValidator),
- typeof(IIdentityProviderConfigurationValidator),
- typeof(IIntrospectionRequestValidator),
- typeof(IJwtRequestValidator),
- typeof(IPushedAuthorizationRequestValidator),
- typeof(IRedirectUriValidator),
- typeof(IResourceOwnerPasswordValidator),
- typeof(IResourceValidator),
- typeof(IScopeParser),
- typeof(ISecretParser),
- typeof(ISecretsListParser),
- typeof(ISecretsListValidator),
- typeof(ISecretValidator),
- typeof(ITokenRequestValidator),
- typeof(ITokenRevocationRequestValidator),
- typeof(ITokenValidator),
- typeof(IUserInfoRequestValidator)
+ new(typeof(IApiSecretValidator),[typeof(ApiSecretValidator)]),
+ new(typeof(IAuthorizeRequestValidator), [typeof(AuthorizeRequestValidator)]),
+ new(typeof(IBackchannelAuthenticationRequestIdValidator), [typeof(BackchannelAuthenticationRequestIdValidator)]),
+ new(typeof(IBackchannelAuthenticationRequestValidator), [typeof(BackchannelAuthenticationRequestValidator)]),
+ new(typeof(IBackchannelAuthenticationUserValidator), [typeof(NopBackchannelAuthenticationUserValidator)]),
+ new(typeof(IClientConfigurationValidator), [typeof(DefaultClientConfigurationValidator)]),
+ new(typeof(IClientSecretValidator), [typeof(ClientSecretValidator)]),
+ new(typeof(ICustomAuthorizeRequestValidator), [typeof(DefaultCustomAuthorizeRequestValidator)]),
+ new(typeof(ICustomBackchannelAuthenticationValidator), [typeof(DefaultCustomBackchannelAuthenticationValidator)]),
+ new(typeof(ICustomTokenRequestValidator), [typeof(DefaultCustomTokenRequestValidator)]),
+ new(typeof(ICustomTokenValidator), [typeof(DefaultCustomTokenValidator)]),
+ new(typeof(IDeviceAuthorizationRequestValidator), [typeof(DeviceAuthorizationRequestValidator)]),
+ new(typeof(IDeviceCodeValidator), [typeof(DeviceCodeValidator)]),
+ new(typeof(IDPoPProofValidator), [typeof(DefaultDPoPProofValidator)]),
+ new(typeof(IEndSessionRequestValidator), [typeof(EndSessionRequestValidator)]),
+ new(typeof(IExtensionGrantValidator), []),
+ new(typeof(IIdentityProviderConfigurationValidator), [typeof(DefaultIdentityProviderConfigurationValidator)]),
+ new(typeof(IIntrospectionRequestValidator), [typeof(IntrospectionRequestValidator)]),
+ new(typeof(IJwtRequestValidator), [typeof(JwtRequestValidator)]),
+ new(typeof(IPushedAuthorizationRequestValidator), [typeof(PushedAuthorizationRequestValidator)]),
+ new(typeof(IRedirectUriValidator), [typeof(StrictRedirectUriValidator)]),
+ new(typeof(IResourceOwnerPasswordValidator), [typeof(NotSupportedResourceOwnerPasswordValidator)]),
+ new(typeof(IResourceValidator), [typeof(DefaultResourceValidator)]),
+ new(typeof(IScopeParser), [typeof(DefaultScopeParser)]),
+ new(typeof(ISecretParser), [typeof(BasicAuthenticationSecretParser), typeof(PostBodySecretParser)]),
+ new(typeof(ISecretsListParser), [typeof(SecretParser)]),
+ new(typeof(ISecretsListValidator), [typeof(SecretValidator)]),
+ new(typeof(ISecretValidator), [typeof(HashedSharedSecretValidator)]),
+ new(typeof(ITokenRequestValidator),[typeof(TokenRequestValidator)]),
+ new(typeof(ITokenRevocationRequestValidator), [typeof(TokenRevocationRequestValidator)]),
+ new(typeof(ITokenValidator), [typeof(TokenValidator)]),
+ new(typeof(IUserInfoRequestValidator), [typeof(UserInfoRequestValidator)]),
]
}
};
@@ -161,9 +168,9 @@ public Task WriteAsync(Utf8JsonWriter writer)
{
writer.WriteStartArray(group.Key);
- foreach (var type in group.Value)
+ foreach (var implementationInfo in group.Value)
{
- WriteImplementationDetails(type, type.Name, writer);
+ WriteImplementationDetails(implementationInfo, writer);
}
writer.WriteEndArray();
@@ -174,36 +181,31 @@ public Task WriteAsync(Utf8JsonWriter writer)
return Task.CompletedTask;
}
- private void WriteImplementationDetails(Type targetType, string serviceName, Utf8JsonWriter writer)
+ private void WriteImplementationDetails(RegisteredImplementationDetails registeredImplementationDetails, Utf8JsonWriter writer)
{
- writer.WriteStartObject();
- writer.WriteStartArray(serviceName);
-
var services = serviceCollectionAccessor.ServiceCollection.Where(descriptor =>
- descriptor.ServiceType == targetType &&
- descriptor.ImplementationType != null);
- if (services.Any())
+ descriptor.ServiceType == registeredImplementationDetails.TInterface &&
+ descriptor.ImplementationType != null &&
+ !registeredImplementationDetails.TDefaultImplementations.Contains(descriptor.ImplementationType));
+
+ if (!services.Any())
{
- foreach (var service in services)
- {
- var type = service.ImplementationType!;
- writer.WriteStartObject();
- writer.WriteString("TypeName", type.FullName);
- writer.WriteString("Assembly", type.Assembly.GetName().Name);
- writer.WriteString("AssemblyVersion", type.Assembly.GetName().Version?.ToString());
- writer.WriteEndObject();
- }
+ return;
}
- else
+
+ writer.WriteStartObject();
+ writer.WriteStartArray(registeredImplementationDetails.TInterface.Name);
+
+ foreach (var service in services)
{
+ var type = service.ImplementationType!;
writer.WriteStartObject();
- writer.WriteString("TypeName", "Not Registered");
- writer.WriteString("Assembly", "Not Registered");
- writer.WriteString("AssemblyVersion", "Not Registered");
+ writer.WriteString("TypeName", type.FullName);
+ writer.WriteString("Assembly", type.Assembly.GetName().Name);
+ writer.WriteString("AssemblyVersion", type.Assembly.GetName().Version?.ToString());
writer.WriteEndObject();
}
-
writer.WriteEndArray();
writer.WriteEndObject();
}
diff --git a/identity-server/test/IdentityServer.UnitTests/Licensing/v2/DiagnosticEntries/RegisteredImplementationsDiagnosticEntryTests.cs b/identity-server/test/IdentityServer.UnitTests/Licensing/v2/DiagnosticEntries/RegisteredImplementationsDiagnosticEntryTests.cs
index 3150513a9..918cf1734 100644
--- a/identity-server/test/IdentityServer.UnitTests/Licensing/v2/DiagnosticEntries/RegisteredImplementationsDiagnosticEntryTests.cs
+++ b/identity-server/test/IdentityServer.UnitTests/Licensing/v2/DiagnosticEntries/RegisteredImplementationsDiagnosticEntryTests.cs
@@ -1,20 +1,40 @@
// Copyright (c) Duende Software. All rights reserved.
// See LICENSE in the project root for license information.
+using System.Reflection;
using Duende.IdentityServer.Licensing.V2;
using Duende.IdentityServer.Licensing.V2.Diagnostics.DiagnosticEntries;
using Duende.IdentityServer.Services;
+using Duende.IdentityServer.Validation;
using Microsoft.Extensions.DependencyInjection;
using UnitTests.Common;
+using UnitTests.Validation.Setup;
namespace IdentityServer.UnitTests.Licensing.V2.DiagnosticEntries;
public class RegisteredImplementationsDiagnosticEntryTests
{
[Fact]
- public async Task WriteAsync_ShouldWriteRegisteredImplementationInfo()
+ public async Task Should_Not_Write_NonDefault_Implementations()
{
var serviceCollection = new ServiceCollection()
+ .AddSingleton() // Default
+ .AddSingleton(); // Default
+ var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(serviceCollection));
+
+ var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
+
+ var registeredImplementations = result.RootElement.GetProperty("RegisteredImplementations");
+ registeredImplementations.TryGetProperty("Services", out _).ShouldBeTrue();
+ var services = registeredImplementations.GetProperty("Services");
+ services.EnumerateArray().Any(entry => entry.TryGetProperty(nameof(ISecretParser), out _)).ShouldBeFalse();
+ }
+
+ [Fact]
+ public async Task Should_Write_Type_Information_For_Non_Default_Implementation()
+ {
+ var serviceCollection = new ServiceCollection()
+ .AddSingleton()
.AddSingleton();
var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(serviceCollection));
@@ -22,7 +42,7 @@ public async Task WriteAsync_ShouldWriteRegisteredImplementationInfo()
var registeredImplementations = result.RootElement.GetProperty("RegisteredImplementations");
var services = registeredImplementations.GetProperty("Services");
- var profileServiceEntry = services.EnumerateArray().ToList().SingleOrDefault(entry => entry.TryGetProperty(nameof(IProfileService), out _));
+ var profileServiceEntry = services.EnumerateArray().SingleOrDefault(entry => entry.TryGetProperty(nameof(IProfileService), out _));
var assemblyInfo = profileServiceEntry.GetProperty(nameof(IProfileService)).EnumerateArray().First();
var expectedTypeInfo = typeof(MockProfileService);
assemblyInfo.GetProperty("TypeName").GetString().ShouldBe(expectedTypeInfo.FullName);
@@ -31,7 +51,7 @@ public async Task WriteAsync_ShouldWriteRegisteredImplementationInfo()
}
[Fact]
- public async Task WriteAsync_GroupsImplementationsByCategory()
+ public async Task Should_Group_Registered_Implementations_By_Category()
{
var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(new ServiceCollection()));
@@ -48,10 +68,10 @@ public async Task WriteAsync_GroupsImplementationsByCategory()
}
[Fact]
- public async Task WriteAsync_HandlesMultipleRegistrationsForAService()
+ public async Task Should_Handle_Multiple_Registered_Non_Default_Implementations()
{
var serviceCollection = new ServiceCollection()
- .AddSingleton()
+ .AddSingleton()
.AddSingleton();
var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(serviceCollection));
@@ -59,9 +79,9 @@ public async Task WriteAsync_HandlesMultipleRegistrationsForAService()
var registeredImplementations = result.RootElement.GetProperty("RegisteredImplementations");
var services = registeredImplementations.GetProperty("Services");
- var profileServiceEntry = services.EnumerateArray().ToList().SingleOrDefault(entry => entry.TryGetProperty(nameof(IProfileService), out _));
+ var profileServiceEntry = services.EnumerateArray().SingleOrDefault(entry => entry.TryGetProperty(nameof(IProfileService), out _));
var firstAssemblyInfo = profileServiceEntry.GetProperty(nameof(IProfileService)).EnumerateArray().First();
- var firstExpectedTypeInfo = typeof(DefaultProfileService);
+ var firstExpectedTypeInfo = typeof(TestProfileService);
firstAssemblyInfo.GetProperty("TypeName").GetString().ShouldBe(firstExpectedTypeInfo.FullName);
firstAssemblyInfo.GetProperty("Assembly").GetString().ShouldBe(firstExpectedTypeInfo.Assembly.GetName().Name);
firstAssemblyInfo.GetProperty("AssemblyVersion").GetString().ShouldBe(firstExpectedTypeInfo.Assembly.GetName().Version?.ToString());
@@ -73,7 +93,7 @@ public async Task WriteAsync_HandlesMultipleRegistrationsForAService()
}
[Fact]
- public async Task WriteAsync_HandlesNoServiceRegisteredForInterface()
+ public async Task Should_Handle_No_Non_Default_Implementations_Registered()
{
var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(new ServiceCollection()));
@@ -81,29 +101,24 @@ public async Task WriteAsync_HandlesNoServiceRegisteredForInterface()
var registeredImplementations = result.RootElement.GetProperty("RegisteredImplementations");
var services = registeredImplementations.GetProperty("Services");
- var profileServiceEntry = services.EnumerateArray().ToList().SingleOrDefault(entry => entry.TryGetProperty(nameof(IProfileService), out _));
- var assemblyInfo = profileServiceEntry.GetProperty(nameof(IProfileService)).EnumerateArray().First();
- assemblyInfo.GetProperty("TypeName").GetString().ShouldBe("Not Registered");
- assemblyInfo.GetProperty("Assembly").GetString().ShouldBe("Not Registered");
- assemblyInfo.GetProperty("AssemblyVersion").GetString().ShouldBe("Not Registered");
+ services.EnumerateArray().Any(entry => entry.TryGetProperty(nameof(IProfileService), out _)).ShouldBeFalse();
}
[Fact]
- public async Task WriteAsync_ShouldIncludeAllPublicInterfaces()
+ public void Should_Track_All_Public_Interfaces()
{
var interfaces = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetExportedTypes())
.Where(type => type.IsInterface && type.IsPublic && type.Namespace != null &&
type.Namespace.StartsWith(
"Duende.IdentityServer"))
- .Select(type => type.Name);
+ .Select(type => type);
var subject = new RegisteredImplementationsDiagnosticEntry(new ServiceCollectionAccessor(new ServiceCollection()));
+ var typesTrackedField = typeof(RegisteredImplementationsDiagnosticEntry)
+ .GetField("_typesToInspect", BindingFlags.NonPublic | BindingFlags.Instance)
+ ?.GetValue(subject) as Dictionary>;
+ var typesTracked = typesTrackedField?.SelectMany(kvp => kvp.Value).Select(details => details.TInterface);
- var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
-
- var registeredImplementations = result.RootElement.GetProperty("RegisteredImplementations");
- var entries = registeredImplementations.EnumerateObject()
- .SelectMany(property => property.Value.EnumerateArray()).Select(element => element.EnumerateObject().First().Name);
- entries.ShouldBe(interfaces, ignoreOrder: true);
+ typesTracked.ShouldBe(interfaces, ignoreOrder: true);
}
}