FIX: Deleting language can make the backoffice client unusable (#16863)

* Make missing languages a non blocker for usergroup retrieval

* Add logging

* Update obsolete message

---------

Co-authored-by: Zeegaan <skrivdetud@gmail.com>
This commit is contained in:
Sven Geusens
2024-08-05 13:30:18 +02:00
committed by GitHub
parent 4cd2f4637b
commit 18d2656414

View File

@@ -1,11 +1,12 @@
using Umbraco.Cms.Api.Management.Mapping;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Api.Management.Mapping;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Api.Management.ViewModels.UserGroup;
using Umbraco.Cms.Api.Management.ViewModels.UserGroup.Permissions;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Models.Membership.Permissions;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Core.Strings;
@@ -20,17 +21,30 @@ public class UserGroupPresentationFactory : IUserGroupPresentationFactory
private readonly IShortStringHelper _shortStringHelper;
private readonly ILanguageService _languageService;
private readonly IPermissionPresentationFactory _permissionPresentationFactory;
private readonly ILogger<UserGroupPresentationFactory> _logger;
[Obsolete("Use the new constructor instead, will be removed in v16.")]
public UserGroupPresentationFactory(
IEntityService entityService,
IShortStringHelper shortStringHelper,
ILanguageService languageService,
IPermissionPresentationFactory permissionPresentationFactory)
: this(entityService, shortStringHelper, languageService, permissionPresentationFactory, StaticServiceProvider.Instance.GetRequiredService<ILogger<UserGroupPresentationFactory>>())
{
}
public UserGroupPresentationFactory(
IEntityService entityService,
IShortStringHelper shortStringHelper,
ILanguageService languageService,
IPermissionPresentationFactory permissionPresentationFactory,
ILogger<UserGroupPresentationFactory> logger)
{
_entityService = entityService;
_shortStringHelper = shortStringHelper;
_languageService = languageService;
_permissionPresentationFactory = permissionPresentationFactory;
_logger = logger;
}
/// <inheritdoc />
@@ -43,10 +57,9 @@ public class UserGroupPresentationFactory : IUserGroupPresentationFactory
Attempt<IEnumerable<string>, UserGroupOperationStatus> languageIsoCodesMappingAttempt = await MapLanguageIdsToIsoCodeAsync(userGroup.AllowedLanguages);
// We've gotten this data from the database, so the mapping should not fail
if (languageIsoCodesMappingAttempt.Success is false)
{
throw new InvalidOperationException($"Unknown language ID in User Group: {userGroup.Name}");
_logger.LogDebug("Unknown language ID in User Group: {0}", userGroup.Name);
}
return new UserGroupResponseModel
@@ -77,10 +90,9 @@ public class UserGroupPresentationFactory : IUserGroupPresentationFactory
Guid? mediaStartNodeKey = GetKeyFromId(userGroup.StartMediaId, UmbracoObjectTypes.Media);
Attempt<IEnumerable<string>, UserGroupOperationStatus> languageIsoCodesMappingAttempt = await MapLanguageIdsToIsoCodeAsync(userGroup.AllowedLanguages);
// We've gotten this data from the database, so the mapping should not fail
if (languageIsoCodesMappingAttempt.Success is false)
{
throw new InvalidOperationException($"Unknown language ID in User Group: {userGroup.Name}");
_logger.LogDebug("Unknown language ID in User Group: {0}", userGroup.Name);
}
return new UserGroupResponseModel
@@ -217,9 +229,10 @@ public class UserGroupPresentationFactory : IUserGroupPresentationFactory
.Select(x => x.IsoCode)
.ToArray();
return isoCodes.Length == ids.Count()
? Attempt.SucceedWithStatus<IEnumerable<string>, UserGroupOperationStatus>(UserGroupOperationStatus.Success, isoCodes)
: Attempt.FailWithStatus<IEnumerable<string>, UserGroupOperationStatus>(UserGroupOperationStatus.LanguageNotFound, isoCodes);
// if a language id does not exist, it simply not returned.
// We do this so we don't have to clean up user group data when deleting languages and to make it easier to restore accidentally removed languages
return Attempt.SucceedWithStatus<IEnumerable<string>, UserGroupOperationStatus>(
UserGroupOperationStatus.Success, isoCodes);
}
private async Task<Attempt<IEnumerable<int>, UserGroupOperationStatus>> MapLanguageIsoCodesToIdsAsync(IEnumerable<string> isoCodes)