private static void RegisterNotificationHandler(IUmbracoBuilder self, Type notificationHandlerType, Type implementingHandlerType) { var descriptor = new UniqueServiceDescriptor(notificationHandlerType, implementingHandlerType, ServiceLifetime.Transient); if (!self.Services.Contains(descriptor)) { self.Services.Add(descriptor); } }
/// <summary> /// Adds Identity support for Umbraco members /// </summary> public static IUmbracoBuilder AddMembersIdentity(this IUmbracoBuilder builder) { IServiceCollection services = builder.Services; // check if this has already been added, we cannot add twice but both front-end and back end // depend on this so it's possible it can be called twice. var distCacheBinder = new UniqueServiceDescriptor(typeof(IMemberManager), typeof(MemberManager), ServiceLifetime.Scoped); if (builder.Services.Contains(distCacheBinder)) { return(builder); } // NOTE: We are using AddIdentity which is going to add all of the default AuthN/AuthZ configurations = OK! // This will also add all of the default identity services for our user/role types that we aren't overriding = OK! // If a developer wishes to use Umbraco Members with different AuthN/AuthZ values, like different cookie values // or authentication scheme's then they can call the default identity configuration methods like ConfigureApplicationCookie. // BUT ... if a developer wishes to use the default auth schemes for entirely separate purposes alongside Umbraco members, // then we'll probably have to change this and make it more flexible like how we do for Users. Which means booting up // identity here with the basics and registering all of our own custom services. // Since we are using the defaults in v8 (and below) for members, I think using the default for members now is OK! services.AddIdentity <MemberIdentityUser, UmbracoIdentityRole>() .AddDefaultTokenProviders() .AddUserStore <IUserStore <MemberIdentityUser>, MemberUserStore>(factory => new MemberUserStore( factory.GetRequiredService <IMemberService>(), factory.GetRequiredService <IUmbracoMapper>(), factory.GetRequiredService <IScopeProvider>(), factory.GetRequiredService <IdentityErrorDescriber>(), factory.GetRequiredService <IPublishedSnapshotAccessor>(), factory.GetRequiredService <IExternalLoginWithKeyService>(), factory.GetRequiredService <ITwoFactorLoginService>() )) .AddRoleStore <MemberRoleStore>() .AddRoleManager <IMemberRoleManager, MemberRoleManager>() .AddMemberManager <IMemberManager, MemberManager>() .AddSignInManager <IMemberSignInManager, MemberSignInManager>() .AddSignInManager <IMemberSignInManagerExternalLogins, MemberSignInManager>() .AddErrorDescriber <MembersErrorDescriber>() .AddUserConfirmation <UmbracoUserConfirmation <MemberIdentityUser> >(); builder.AddNotificationHandler <MemberDeletedNotification, DeleteExternalLoginsOnMemberDeletedHandler>(); builder.AddNotificationAsyncHandler <MemberDeletedNotification, DeleteTwoFactorLoginsOnMemberDeletedHandler>(); services.ConfigureOptions <ConfigureMemberIdentityOptions>(); services.AddScoped <IMemberUserStore>(x => (IMemberUserStore)x.GetRequiredService <IUserStore <MemberIdentityUser> >()); services.AddScoped <IPasswordHasher <MemberIdentityUser>, MemberPasswordHasher>(); services.ConfigureOptions <ConfigureSecurityStampOptions>(); services.ConfigureOptions <ConfigureMemberCookieOptions>(); services.AddUnique <IMemberExternalLoginProviders, MemberExternalLoginProviders>(); return(builder); }
/// <summary> /// Adds umbraco's embedded model builder support /// </summary> public static IUmbracoBuilder AddModelsBuilder(this IUmbracoBuilder builder) { var umbServices = new UniqueServiceDescriptor(typeof(UmbracoServices), typeof(UmbracoServices), ServiceLifetime.Singleton); if (builder.Services.Contains(umbServices)) { // if this ext method is called more than once just exit return(builder); } builder.Services.Add(umbServices); builder.AddInMemoryModelsRazorEngine(); // TODO: I feel like we could just do builder.AddNotificationHandler<ModelsBuilderNotificationHandler>() and it // would automatically just register for all implemented INotificationHandler{T}? builder.AddNotificationHandler <TemplateSavingNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <ServerVariablesParsingNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <ModelBindingErrorNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <UmbracoApplicationStartingNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <UmbracoRequestEndNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <ContentTypeCacheRefresherNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <DataTypeCacheRefresherNotification, AutoModelsNotificationHandler>(); builder.Services.AddSingleton <ModelsGenerator>(); builder.Services.AddSingleton <OutOfDateModelsStatus>(); builder.AddNotificationHandler <ContentTypeCacheRefresherNotification, OutOfDateModelsStatus>(); builder.AddNotificationHandler <DataTypeCacheRefresherNotification, OutOfDateModelsStatus>(); builder.Services.AddSingleton <ModelsGenerationError>(); builder.Services.AddSingleton <InMemoryModelFactory>(); // This is what the community MB would replace, all of the above services are fine to be registered // even if the community MB is in place. builder.Services.AddSingleton <IPublishedModelFactory>(factory => { ModelsBuilderSettings config = factory.GetRequiredService <IOptions <ModelsBuilderSettings> >().Value; if (config.ModelsMode == ModelsMode.InMemoryAuto) { return(factory.GetRequiredService <InMemoryModelFactory>()); } else { return(factory.CreateDefaultPublishedModelFactory()); } }); if (!builder.Services.Any(x => x.ServiceType == typeof(IModelsBuilderDashboardProvider))) { builder.Services.AddUnique <IModelsBuilderDashboardProvider, NoopModelsBuilderDashboardProvider>(); } return(builder); }
/// <summary> /// Adds a <see cref="UserManager{TUser}"/> for the <seealso cref="MemberIdentityUser"/>. /// </summary> /// <typeparam name="TInterface">The member manager interface</typeparam> /// <typeparam name="TUserManager">The member manager type</typeparam> /// <returns>The current <see cref="IdentityBuilder"/> instance.</returns> public static IdentityBuilder AddMemberManager <TInterface, TUserManager>(this IdentityBuilder identityBuilder) where TUserManager : UserManager <MemberIdentityUser>, TInterface { identityBuilder.AddUserManager <TUserManager>(); // use a UniqueServiceDescriptor so we can check if it's already been added var memberManagerDescriptor = new UniqueServiceDescriptor(typeof(TInterface), typeof(TUserManager), ServiceLifetime.Scoped); identityBuilder.Services.Add(memberManagerDescriptor); identityBuilder.Services.AddScoped(typeof(UserManager <MemberIdentityUser>), factory => factory.GetRequiredService <TInterface>()); return(identityBuilder); }
internal static IServiceCollection AddNotificationHandler <TNotification, TNotificationHandler>( this IServiceCollection services) where TNotificationHandler : INotificationHandler <TNotification> where TNotification : INotification { // Register the handler as transient. This ensures that anything can be injected into it. var descriptor = new UniqueServiceDescriptor( typeof(INotificationHandler <TNotification>), typeof(TNotificationHandler), ServiceLifetime.Transient); if (!services.Contains(descriptor)) { services.Add(descriptor); } return(services); }
/// <summary> /// Adds umbraco's embedded model builder support /// </summary> public static IUmbracoBuilder AddModelsBuilder(this IUmbracoBuilder builder) { var umbServices = new UniqueServiceDescriptor(typeof(UmbracoServices), typeof(UmbracoServices), ServiceLifetime.Singleton); if (builder.Services.Contains(umbServices)) { // if this ext method is called more than once just exit return(builder); } builder.Services.Add(umbServices); if (builder.Config.GetRuntimeMode() == RuntimeMode.BackofficeDevelopment) { // Configure services to allow InMemoryAuto mode builder.AddInMemoryModelsRazorEngine(); builder.AddNotificationHandler <ModelBindingErrorNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <ContentTypeCacheRefresherNotification, OutOfDateModelsStatus>(); builder.AddNotificationHandler <DataTypeCacheRefresherNotification, OutOfDateModelsStatus>(); } if (builder.Config.GetRuntimeMode() != RuntimeMode.Production) { // Configure service to allow models generation builder.AddNotificationHandler <ServerVariablesParsingNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <TemplateSavingNotification, ModelsBuilderNotificationHandler>(); builder.AddNotificationHandler <UmbracoApplicationStartingNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <UmbracoRequestEndNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <ContentTypeCacheRefresherNotification, AutoModelsNotificationHandler>(); builder.AddNotificationHandler <DataTypeCacheRefresherNotification, AutoModelsNotificationHandler>(); } builder.Services.TryAddSingleton <IModelsBuilderDashboardProvider, NoopModelsBuilderDashboardProvider>(); // Register required services for ModelsBuilderDashboardController builder.Services.AddSingleton <ModelsGenerator>(); builder.Services.AddSingleton <OutOfDateModelsStatus>(); builder.Services.AddSingleton <ModelsGenerationError>(); return(builder); }