From ac6b205e7feca5fdbe2ac175678cd93764b45d22 Mon Sep 17 00:00:00 2001 From: Mitchel <12159221+KaasKop97@users.noreply.github.com> Date: Mon, 29 Sep 2025 15:07:30 +0000 Subject: [PATCH] Unattended install: Added the ability to set the telemetry level (#20249) * Added the ability to set the telemetry level for an unattended install Added 'UnattendedTelemetryLevel' to 'UnattendedSettings' Renamed 'CreateUnattendedUserNotificationHandler' to 'PostUnattendedInstallNotificationHandler' Set the telemetry level in the unattended install notification handler * Add DefaultValue attribute to 'UnattendedTelemetryLevel' * Added UnattendedTelemetryLevel to template. * Updated cli and ide hosts. --------- Co-authored-by: Andy Butland --- .../InstallerBuilderExtensions.cs | 2 +- ...stUnattendedInstallNotificationHandler.cs} | 14 +++++--- .../Models/UnattendedSettings.cs | 8 +++++ .../.template.config/dotnetcli.host.json | 4 +++ .../.template.config/ide.host.json | 5 +++ .../.template.config/template.json | 32 +++++++++++++++++-- .../appsettings.Development.json | 3 +- 7 files changed, 59 insertions(+), 9 deletions(-) rename src/Umbraco.Cms.Api.Management/Install/{CreateUnattendedUserNotificationHandler.cs => PostUnattendedInstallNotificationHandler.cs} (82%) diff --git a/src/Umbraco.Cms.Api.Management/DependencyInjection/InstallerBuilderExtensions.cs b/src/Umbraco.Cms.Api.Management/DependencyInjection/InstallerBuilderExtensions.cs index 88d95b2fbd..57166989dd 100644 --- a/src/Umbraco.Cms.Api.Management/DependencyInjection/InstallerBuilderExtensions.cs +++ b/src/Umbraco.Cms.Api.Management/DependencyInjection/InstallerBuilderExtensions.cs @@ -25,7 +25,7 @@ public static class InstallerBuilderExtensions builder.AddInstallSteps(); services.AddTransient(); - builder.AddNotificationAsyncHandler(); + builder.AddNotificationAsyncHandler(); builder.WithCollectionBuilder().Add(); return builder; diff --git a/src/Umbraco.Cms.Api.Management/Install/CreateUnattendedUserNotificationHandler.cs b/src/Umbraco.Cms.Api.Management/Install/PostUnattendedInstallNotificationHandler.cs similarity index 82% rename from src/Umbraco.Cms.Api.Management/Install/CreateUnattendedUserNotificationHandler.cs rename to src/Umbraco.Cms.Api.Management/Install/PostUnattendedInstallNotificationHandler.cs index 0a96dcbe6b..5764110d6c 100644 --- a/src/Umbraco.Cms.Api.Management/Install/CreateUnattendedUserNotificationHandler.cs +++ b/src/Umbraco.Cms.Api.Management/Install/PostUnattendedInstallNotificationHandler.cs @@ -12,27 +12,31 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Install; -public class CreateUnattendedUserNotificationHandler : INotificationAsyncHandler +public class PostUnattendedInstallNotificationHandler : INotificationAsyncHandler { private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IOptions _unattendedSettings; private readonly IUserService _userService; + private readonly IMetricsConsentService _metricsConsentService; - public CreateUnattendedUserNotificationHandler(IOptions unattendedSettings, IUserService userService, IServiceScopeFactory serviceScopeFactory) + public PostUnattendedInstallNotificationHandler(IOptions unattendedSettings, IUserService userService, IServiceScopeFactory serviceScopeFactory, IMetricsConsentService metricsConsentService) { _unattendedSettings = unattendedSettings; _userService = userService; _serviceScopeFactory = serviceScopeFactory; + _metricsConsentService = metricsConsentService; } /// - /// Listening for when the UnattendedInstallNotification fired after a sucessfulk + /// Listening for when the UnattendedInstallNotification fired after a successful unattended install + /// This creates the user and sets the telemetry level based on the 'Unattended' settings. /// /// /// public async Task HandleAsync(UnattendedInstallNotification notification, CancellationToken cancellationToken) { UnattendedSettings? unattendedSettings = _unattendedSettings.Value; + // Ensure we have the setting enabled (Sanity check) // In theory this should always be true as the event only fired when a sucessfull if (_unattendedSettings.Value.InstallUnattended == false) @@ -83,7 +87,7 @@ public class CreateUnattendedUserNotificationHandler : INotificationAsyncHandler $"No user found in membership provider with id of {Constants.Security.SuperUserIdAsString}."); } - //To change the password here we actually need to reset it since we don't have an old one to use to change + // To change the password here we actually need to reset it since we don't have an old one to use to change var resetToken = await backOfficeUserManager.GeneratePasswordResetTokenAsync(membershipUser); if (string.IsNullOrWhiteSpace(resetToken)) { @@ -98,5 +102,7 @@ public class CreateUnattendedUserNotificationHandler : INotificationAsyncHandler throw new InvalidOperationException("Could not reset password: " + string.Join(", ", resetResult.Errors.ToErrorMessage())); } + + await _metricsConsentService.SetConsentLevelAsync(unattendedSettings.UnattendedTelemetryLevel); } } diff --git a/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs b/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs index 577fb9a2d9..30b3bb3d5e 100644 --- a/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Configuration.Models; @@ -14,6 +15,7 @@ public class UnattendedSettings { private const bool StaticInstallUnattended = false; private const bool StaticUpgradeUnattended = false; + private const TelemetryLevel StaticTelemetryLevel = TelemetryLevel.Detailed; /// /// Gets or sets a value indicating whether unattended installs are enabled. @@ -58,4 +60,10 @@ public class UnattendedSettings /// Gets or sets a value to use for creating a user with a password for Unattended Installs /// public string? UnattendedUserPassword { get; set; } = null; + + /// + /// Gets or sets a telemetry level to use for Unattended Installs + /// + [DefaultValue(StaticTelemetryLevel)] + public TelemetryLevel UnattendedTelemetryLevel { get; set; } = StaticTelemetryLevel; } diff --git a/templates/UmbracoProject/.template.config/dotnetcli.host.json b/templates/UmbracoProject/.template.config/dotnetcli.host.json index b18020b6de..d9ce34789e 100644 --- a/templates/UmbracoProject/.template.config/dotnetcli.host.json +++ b/templates/UmbracoProject/.template.config/dotnetcli.host.json @@ -63,6 +63,10 @@ "longName": "password", "shortName": "" }, + "UnattendedTelemetryLevel": { + "longName": "telemetry-level", + "shortName": "" + }, "NoNodesViewPath": { "longName": "no-nodes-view-path", "shortName": "" diff --git a/templates/UmbracoProject/.template.config/ide.host.json b/templates/UmbracoProject/.template.config/ide.host.json index 90de3b977a..364b68bc35 100644 --- a/templates/UmbracoProject/.template.config/ide.host.json +++ b/templates/UmbracoProject/.template.config/ide.host.json @@ -62,6 +62,11 @@ "id": "UnattendedUserPassword", "isVisible": true }, + { + "id": "UnattendedTelemetryLevel", + "isVisible": true, + "defaultValue": "Detailed" + }, { "id": "NoNodesViewPath", "isVisible": true diff --git a/templates/UmbracoProject/.template.config/template.json b/templates/UmbracoProject/.template.config/template.json index 7909452deb..57b75f5976 100644 --- a/templates/UmbracoProject/.template.config/template.json +++ b/templates/UmbracoProject/.template.config/template.json @@ -82,7 +82,7 @@ "replaces": "CUSTOM_VERSION", "isRequired": false }, - "FinalVersion" : { + "FinalVersion": { "type": "generated", "generator": "switch", "datatype": "text", @@ -103,8 +103,7 @@ ] } }, - "DotnetVersion": - { + "DotnetVersion": { "type": "generated", "generator": "switch", "datatype": "text", @@ -300,6 +299,33 @@ }, "replaces": "UNATTENDED_USER_PASSWORD_FROM_TEMPLATE" }, + "UnattendedTelemetryLevel": { + "displayName": "Unattended telemetry level", + "description": "Specifies the level of telemetry information the installation will report.", + "type": "parameter", + "datatype": "choice", + "defaultValue": "Detailed", + "choices": [ + { + "choice": "Minimal", + "description": "Minimal information" + }, + { + "choice": "Basic", + "description": "Basic information" + }, + { + "choice": "Detailed", + "description": "Detailed information" + } + ], + "forms": { + "global": [ + "jsonEncode" + ] + }, + "replaces": "UNATTENDED_TELEMETRY_LEVEL_FROM_TEMPLATE" + }, "UsingUnattenedInstall": { "type": "computed", "value": "(UnattendedUserName != '' && UnattendedUserEmail != '' && UnattendedUserPassword != '' && (HasConnectionString || HasDevelopmentConnectionString))" diff --git a/templates/UmbracoProject/appsettings.Development.json b/templates/UmbracoProject/appsettings.Development.json index 0521b835ed..be0baeafff 100644 --- a/templates/UmbracoProject/appsettings.Development.json +++ b/templates/UmbracoProject/appsettings.Development.json @@ -35,7 +35,8 @@ "InstallUnattended": true, "UnattendedUserName": "UNATTENDED_USER_NAME_FROM_TEMPLATE", "UnattendedUserEmail": "UNATTENDED_USER_EMAIL_FROM_TEMPLATE", - "UnattendedUserPassword": "UNATTENDED_USER_PASSWORD_FROM_TEMPLATE" + "UnattendedUserPassword": "UNATTENDED_USER_PASSWORD_FROM_TEMPLATE", + "UnattendedTelemetryLevel": "UNATTENDED_TELEMETRY_LEVEL_FROM_TEMPLATE" }, //#endif "Content": {