Installer: Fix issues with newsletter signup (#20705)
* Add setter to allow handling of requests to subscribe to newsletter on install. * Correct serialization of newsletter subscription request. * Fix serialization and use the Umbraco.EmailMarketing service for newsletter signup. * Remove logging of user when setting telemetry level. * Applied suggestions from code review.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.Installer;
|
||||
@@ -17,5 +17,5 @@ public class UserInstallRequestModel
|
||||
[PasswordPropertyText]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
public bool SubscribeToNewsletter { get; }
|
||||
public bool SubscribeToNewsletter { get; set; }
|
||||
}
|
||||
|
||||
@@ -39,11 +39,10 @@ public class MetricsConsentService : IMetricsConsentService
|
||||
return analyticsLevel;
|
||||
}
|
||||
|
||||
public async Task SetConsentLevelAsync(TelemetryLevel telemetryLevel)
|
||||
public Task SetConsentLevelAsync(TelemetryLevel telemetryLevel)
|
||||
{
|
||||
IUser? currentUser = _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser ?? await _userService.GetAsync(Constants.Security.SuperUserKey);
|
||||
|
||||
_logger.LogInformation("Telemetry level set to {telemetryLevel} by {username}", telemetryLevel, currentUser?.Username);
|
||||
_logger.LogInformation("Telemetry level set to {telemetryLevel}", telemetryLevel);
|
||||
_keyValueService.SetValue(Key, telemetryLevel.ToString());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Installer;
|
||||
using Umbraco.Cms.Core.Models.Installer;
|
||||
using Umbraco.Cms.Core.Models.Membership;
|
||||
@@ -32,7 +33,9 @@ public class CreateUserStep : StepBase, IInstallStep
|
||||
private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator;
|
||||
private readonly IMetricsConsentService _metricsConsentService;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILogger<CreateUserStep> _logger;
|
||||
|
||||
[Obsolete("Please use the constructor that takes all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public CreateUserStep(
|
||||
IUserService userService,
|
||||
DatabaseBuilder databaseBuilder,
|
||||
@@ -44,22 +47,50 @@ public class CreateUserStep : StepBase, IInstallStep
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IMetricsConsentService metricsConsentService,
|
||||
IJsonSerializer jsonSerializer)
|
||||
: this(
|
||||
userService,
|
||||
databaseBuilder,
|
||||
httpClientFactory,
|
||||
securitySettings,
|
||||
connectionStrings,
|
||||
cookieManager,
|
||||
userManager,
|
||||
dbProviderFactoryCreator,
|
||||
metricsConsentService,
|
||||
jsonSerializer,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILogger<CreateUserStep>>())
|
||||
{
|
||||
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
|
||||
_databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder));
|
||||
}
|
||||
|
||||
public CreateUserStep(
|
||||
IUserService userService,
|
||||
DatabaseBuilder databaseBuilder,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IOptions<SecuritySettings> securitySettings,
|
||||
IOptionsMonitor<ConnectionStrings> connectionStrings,
|
||||
ICookieManager cookieManager,
|
||||
IBackOfficeUserManager userManager,
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IMetricsConsentService metricsConsentService,
|
||||
IJsonSerializer jsonSerializer,
|
||||
ILogger<CreateUserStep> logger)
|
||||
{
|
||||
_userService = userService;
|
||||
_databaseBuilder = databaseBuilder;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_securitySettings = securitySettings.Value ?? throw new ArgumentNullException(nameof(securitySettings));
|
||||
_securitySettings = securitySettings.Value;
|
||||
_connectionStrings = connectionStrings;
|
||||
_cookieManager = cookieManager;
|
||||
_userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
|
||||
_dbProviderFactoryCreator = dbProviderFactoryCreator ?? throw new ArgumentNullException(nameof(dbProviderFactoryCreator));
|
||||
_userManager = userManager;
|
||||
_dbProviderFactoryCreator = dbProviderFactoryCreator;
|
||||
_metricsConsentService = metricsConsentService;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Attempt<InstallationResult>> ExecuteAsync(InstallData model)
|
||||
{
|
||||
IUser? admin = _userService.GetAsync(Constants.Security.SuperUserKey).GetAwaiter().GetResult();
|
||||
IUser? admin = await _userService.GetAsync(Constants.Security.SuperUserKey);
|
||||
if (admin is null)
|
||||
{
|
||||
return FailWithMessage("Could not find the super user");
|
||||
@@ -96,21 +127,54 @@ public class CreateUserStep : StepBase, IInstallStep
|
||||
|
||||
if (model.User.SubscribeToNewsletter)
|
||||
{
|
||||
var values = new NameValueCollection { { "name", admin.Name }, { "email", admin.Email } };
|
||||
var content = new StringContent(_jsonSerializer.Serialize(values), Encoding.UTF8, "application/json");
|
||||
const string EmailCollectorUrl = "https://emailcollector.umbraco.io/api/EmailProxy";
|
||||
|
||||
var emailModel = new EmailModel
|
||||
{
|
||||
Name = admin.Name,
|
||||
Email = admin.Email,
|
||||
UserGroup = [Constants.Security.AdminGroupAlias],
|
||||
};
|
||||
|
||||
HttpClient httpClient = _httpClientFactory.CreateClient();
|
||||
|
||||
using var content = new StringContent(_jsonSerializer.Serialize(emailModel), System.Text.Encoding.UTF8, "application/json");
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = httpClient.PostAsync("https://shop.umbraco.com/base/Ecom/SubmitEmail/installer.aspx", content).Result;
|
||||
// Set a reasonable timeout of 5 seconds for web request to save subscriber.
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
||||
HttpResponseMessage response = await httpClient.PostAsync(EmailCollectorUrl, content, cts.Token);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
_logger.LogInformation("Successfully subscribed the user created on installation to the Umbraco newsletter.");
|
||||
}
|
||||
catch { /* fail in silence */ }
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Failed to subscribe the user created on installation to the Umbraco newsletter. Status code: {StatusCode}", response.StatusCode);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log and move on if a failure occurs, we don't want to block installation for this.
|
||||
_logger.LogError(ex, "Exception occurred while trying to subscribe the user created on installation to the Umbraco newsletter.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Model used to subscribe to the newsletter. Aligns with EmailModel defined in Umbraco.EmailMarketing.
|
||||
/// </summary>
|
||||
private class EmailModel
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
|
||||
public required string Email { get; init; }
|
||||
|
||||
public required List<string> UserGroup { get; init; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<bool> RequiresExecutionAsync(InstallData model)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user