Throw from IUserIdKeyResolver if id/key not found. (#14101)

* Throw from IUserIdKeyResolver if id/key not found. This is too critical to not throw.

* Fixed tests

* Explicitly test that we can resolve super user key/ID from their counterparts

---------

Co-authored-by: kjac <kja@umbraco.dk>
This commit is contained in:
Bjarke Berg
2023-04-14 12:03:25 +02:00
committed by GitHub
parent d625fee1ad
commit 861b883d29
16 changed files with 82 additions and 68 deletions

View File

@@ -152,5 +152,5 @@ internal sealed class ContentEditingService
}
}
private async Task<int> GetUserIdAsync(Guid userKey) => await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
private async Task<int> GetUserIdAsync(Guid userKey) => await _userIdKeyResolver.GetAsync(userKey);
}

View File

@@ -138,7 +138,7 @@ internal sealed class DataTypeContainerService : RepositoryService, IDataTypeCon
_dataTypeContainerRepository.Delete(container);
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, currentUserId, container.Id);
scope.Complete();
@@ -172,7 +172,7 @@ internal sealed class DataTypeContainerService : RepositoryService, IDataTypeCon
_dataTypeContainerRepository.Save(container);
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(auditType, currentUserId, container.Id);
scope.Complete();

View File

@@ -109,7 +109,7 @@ namespace Umbraco.Cms.Core.Services.Implement
Key = key
};
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<EntityContainer, DataTypeContainerOperationStatus> result = _dataTypeContainerService.CreateAsync(container, parentKey, currentUserKey).GetAwaiter().GetResult();
// mimic old service behavior
@@ -175,7 +175,7 @@ namespace Umbraco.Cms.Core.Services.Implement
{
var isNew = container.Id == 0;
Guid? parentKey = isNew && container.ParentId > 0 ? _dataTypeContainerRepository.Get(container.ParentId)?.Key : null;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<EntityContainer, DataTypeContainerOperationStatus> result = isNew
? _dataTypeContainerService.CreateAsync(container, parentKey, currentUserKey).GetAwaiter().GetResult()
@@ -205,7 +205,7 @@ namespace Umbraco.Cms.Core.Services.Implement
return OperationResult.Attempt.NoOperation(evtMsgs);
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<EntityContainer?, DataTypeContainerOperationStatus> result = _dataTypeContainerService.DeleteAsync(container.Key, currentUserKey).GetAwaiter().GetResult();
// mimic old service behavior
return result.Status switch
@@ -235,7 +235,7 @@ namespace Umbraco.Cms.Core.Services.Implement
}
container.Name = name;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<EntityContainer, DataTypeContainerOperationStatus> result = _dataTypeContainerService.UpdateAsync(container, currentUserKey).GetAwaiter().GetResult();
// mimic old service behavior
return result.Status switch
@@ -423,7 +423,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Notifications.Publish(new DataTypeMovedNotification(moveEventInfo, eventMessages).WithStateFrom(movingDataTypeNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ??Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Move, currentUserId, toMove.Id);
scope.Complete();
}
@@ -452,7 +452,7 @@ namespace Umbraco.Cms.Core.Services.Implement
containerKey = container.Key;
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<IDataType, DataTypeOperationStatus> result = CopyAsync(copying, containerKey, currentUserKey).GetAwaiter().GetResult();
// mimic old service behavior
@@ -505,7 +505,7 @@ namespace Umbraco.Cms.Core.Services.Implement
throw new InvalidOperationException("Name cannot be more than 255 characters in length.");
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
SaveAsync(
dataType,
@@ -593,7 +593,7 @@ namespace Umbraco.Cms.Core.Services.Implement
/// <param name="userId">Optional Id of the user issuing the deletion</param>
public void Delete(IDataType dataType, int userId = Constants.Security.SuperUserId)
{
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
DeleteAsync(dataType.Key, currentUserKey).GetAwaiter().GetResult();
}
@@ -651,7 +651,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Notifications.Publish(new DataTypeDeletedNotification(dataType, eventMessages).WithStateFrom(deletingDataTypeNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, currentUserId, dataType.Id);
scope.Complete();
@@ -710,7 +710,7 @@ namespace Umbraco.Cms.Core.Services.Implement
EventMessages eventMessages = EventMessagesFactory.Get();
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
dataType.CreatorId = currentUserId;
using ICoreScope scope = ScopeProvider.CreateCoreScope();

View File

@@ -167,7 +167,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
new DictionaryItemDeletedNotification(dictionaryItem, eventMessages)
.WithStateFrom(deletingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, "Delete DictionaryItem", currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();
@@ -229,7 +229,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
scope.Notifications.Publish(
new DictionaryItemMovedNotification(moveEventInfo, eventMessages).WithStateFrom(movingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Move, "Move DictionaryItem", currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();
@@ -281,7 +281,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
scope.Notifications.Publish(
new DictionaryItemSavedNotification(dictionaryItem, eventMessages).WithStateFrom(savingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(auditType, auditMessage, currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();

View File

@@ -383,7 +383,7 @@ public class FileService : RepositoryService, IFileService
throw new InvalidOperationException("Name cannot be more than 255 characters in length.");
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<ITemplate, TemplateOperationStatus> result = _templateService.CreateForContentTypeAsync(contentTypeAlias, contentTypeName, currentUserKey).GetAwaiter().GetResult();
// mimic old service behavior
@@ -418,7 +418,7 @@ public class FileService : RepositoryService, IFileService
throw new ArgumentOutOfRangeException(nameof(name), "Name cannot be more than 255 characters in length.");
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<ITemplate, TemplateOperationStatus> result = _templateService.CreateAsync(name, alias, content, currentUserKey).GetAwaiter().GetResult();
return result.Result;
}
@@ -495,7 +495,7 @@ public class FileService : RepositoryService, IFileService
"Name cannot be null, empty, contain only white-space characters or be more than 255 characters in length.");
}
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
if (template.Id > 0)
{
_templateService.UpdateAsync(template, currentUserKey).GetAwaiter().GetResult();
@@ -548,7 +548,7 @@ public class FileService : RepositoryService, IFileService
[Obsolete("Please use ITemplateService for template operations - will be removed in Umbraco 15")]
public void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId)
{
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
_templateService.DeleteAsync(alias, currentUserKey).GetAwaiter().GetResult();
}

View File

@@ -7,12 +7,12 @@ public interface IUserIdKeyResolver
/// </summary>
/// <param name="key">The key of the user. </param>
/// <returns>The id of the user, null if the user doesn't exist.</returns>
public Task<int?> GetAsync(Guid key);
public Task<int> GetAsync(Guid key);
/// <summary>
/// Tries to resolve a user id to a user key without fetching the entire user.
/// </summary>
/// <param name="id">The id of the user. </param>
/// <returns>The key of the user, null if the user doesn't exist.</returns>
public Task<Guid?> GetAsync(int id);
public Task<Guid> GetAsync(int id);
}

View File

@@ -144,7 +144,7 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
scope.Notifications.Publish(
new LanguageDeletedNotification(language, eventMessages).WithStateFrom(deletingLanguageNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, "Delete Language", currentUserId, language.Id, UmbracoObjectTypes.Language.GetName());
scope.Complete();
return await Task.FromResult(Attempt.SucceedWithStatus<ILanguage?, LanguageOperationStatus>(LanguageOperationStatus.Success, language));
@@ -197,7 +197,7 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
scope.Notifications.Publish(
new LanguageSavedNotification(language, eventMessages).WithStateFrom(savingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(auditType, auditMessage, currentUserId, language.Id, UmbracoObjectTypes.Language.GetName());
scope.Complete();

View File

@@ -221,7 +221,7 @@ internal class LocalizationService : RepositoryService, ILocalizationService
[Obsolete("Please use IDictionaryItemService for dictionary item operations. Will be removed in V15.")]
public void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId)
{ ;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
if (dictionaryItem.Id > 0)
{
_dictionaryItemService.UpdateAsync(dictionaryItem, currentUserKey).GetAwaiter().GetResult();
@@ -241,7 +241,7 @@ internal class LocalizationService : RepositoryService, ILocalizationService
[Obsolete("Please use IDictionaryItemService for dictionary item operations. Will be removed in V15.")]
public void Delete(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId)
{
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
_dictionaryItemService.DeleteAsync(dictionaryItem.Key, currentUserKey).GetAwaiter().GetResult();
}
@@ -321,7 +321,7 @@ internal class LocalizationService : RepositoryService, ILocalizationService
[Obsolete("Please use ILanguageService for language operations. Will be removed in V15.")]
public void Save(ILanguage language, int userId = Constants.Security.SuperUserId)
{
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
Attempt<ILanguage, LanguageOperationStatus> result = language.Id > 0
? _languageService.UpdateAsync(language, currentUserKey).GetAwaiter().GetResult()
: _languageService.CreateAsync(language, currentUserKey).GetAwaiter().GetResult();
@@ -341,7 +341,7 @@ internal class LocalizationService : RepositoryService, ILocalizationService
[Obsolete("Please use ILanguageService for language operations. Will be removed in V15.")]
public void Delete(ILanguage language, int userId = Constants.Security.SuperUserId)
{
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult() ?? Constants.Security.SuperUserKey;
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
_languageService.DeleteAsync(language.IsoCode, currentUserKey).GetAwaiter().GetResult();
}

View File

@@ -109,5 +109,5 @@ internal sealed class MediaEditingService
}
}
private async Task<int> GetUserIdAsync(Guid userKey) => await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
private async Task<int> GetUserIdAsync(Guid userKey) => await _userIdKeyResolver.GetAsync(userKey);
}

View File

@@ -622,7 +622,7 @@ public class RelationService : RepositoryService, IRelationService
}
_relationTypeRepository.Save(relationType);
var currentUser = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUser = await _userIdKeyResolver.GetAsync(userKey);
Audit(auditType, currentUser, relationType.Id, auditMessage);
scope.Complete();
scope.Notifications.Publish(
@@ -691,7 +691,7 @@ public class RelationService : RepositoryService, IRelationService
}
_relationTypeRepository.Delete(relationType);
var currentUser = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUser = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, currentUser, relationType.Id, "Deleted relation type");
scope.Notifications.Publish(new RelationTypeDeletedNotification(relationType, eventMessages).WithStateFrom(deletingNotification));
scope.Complete();

View File

@@ -100,7 +100,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingEvent));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.New, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
}
@@ -239,7 +239,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(auditType, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
return Attempt.SucceedWithStatus(TemplateOperationStatus.Success, template);
@@ -386,7 +386,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateDeletedNotification(template, eventMessages).WithStateFrom(deletingNotification));
var currentUserId = await _userIdKeyResolver.GetAsync(userKey) ?? Constants.Security.SuperUserId;
var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
Audit(AuditType.Delete, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
return Attempt.SucceedWithStatus<ITemplate?, TemplateOperationStatus>(TemplateOperationStatus.Success, template);

View File

@@ -13,17 +13,17 @@ namespace Umbraco.Cms.Infrastructure.Services.Implement;
internal sealed class UserIdKeyResolver : IUserIdKeyResolver
{
private readonly IScopeProvider _scopeProvider;
private readonly ConcurrentDictionary<Guid, int?> _keyToId = new();
private readonly ConcurrentDictionary<int, Guid?> _idToKey = new();
private readonly ConcurrentDictionary<Guid, int> _keyToId = new();
private readonly ConcurrentDictionary<int, Guid> _idToKey = new();
private readonly SemaphoreSlim _keytToIdLock = new(1, 1);
private readonly SemaphoreSlim _idToKeyLock = new(1, 1);
public UserIdKeyResolver(IScopeProvider scopeProvider) => _scopeProvider = scopeProvider;
/// <inheritdoc/>
public async Task<int?> GetAsync(Guid key)
public async Task<int> GetAsync(Guid key)
{
if (_keyToId.TryGetValue(key, out int? id))
if (_keyToId.TryGetValue(key, out int id))
{
return id;
}
@@ -33,7 +33,7 @@ internal sealed class UserIdKeyResolver : IUserIdKeyResolver
await _keytToIdLock.WaitAsync();
try
{
if (_keyToId.TryGetValue(key, out int? recheckedId))
if (_keyToId.TryGetValue(key, out int recheckedId))
{
// It was added while we were waiting, so we'll just return it
return recheckedId;
@@ -48,7 +48,9 @@ internal sealed class UserIdKeyResolver : IUserIdKeyResolver
.From<UserDto>()
.Where<UserDto>(x => x.Key == key);
int? fetchedId = await scope.Database.ExecuteScalarAsync<int?>(query);
int fetchedId = (await scope.Database.ExecuteScalarAsync<int?>(query))
?? throw new InvalidOperationException("No user found with the specified key");
_keyToId[key] = fetchedId;
return fetchedId;
@@ -60,9 +62,9 @@ internal sealed class UserIdKeyResolver : IUserIdKeyResolver
}
/// <inheritdoc/>
public async Task<Guid?> GetAsync(int id)
public async Task<Guid> GetAsync(int id)
{
if (_idToKey.TryGetValue(id, out Guid? key))
if (_idToKey.TryGetValue(id, out Guid key))
{
return key;
}
@@ -70,7 +72,7 @@ internal sealed class UserIdKeyResolver : IUserIdKeyResolver
await _idToKeyLock.WaitAsync();
try
{
if (_idToKey.TryGetValue(id, out Guid? recheckedKey))
if (_idToKey.TryGetValue(id, out Guid recheckedKey))
{
return recheckedKey;
}
@@ -84,13 +86,11 @@ internal sealed class UserIdKeyResolver : IUserIdKeyResolver
.Where<UserDto>(x => x.Id == id);
string? guidString = await scope.Database.ExecuteScalarAsync<string?>(query);
Guid? fetchedKey = guidString is null ? null : new Guid(guidString);
Guid fetchedKey = guidString is not null
? new Guid(guidString)
: throw new InvalidOperationException("No user found with the specified id");
// For ids we don't want to cache the null value, since unlike keys, it's pretty likely that we'll see collision
if (fetchedKey is not null)
{
_idToKey[id] = fetchedKey;
}
_idToKey[id] = fetchedKey;
return fetchedKey;
}

View File

@@ -577,7 +577,7 @@ public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
await AddLanguages();
// Act
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0);
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), Constants.Security.SuperUserId);
// Assert
await AssertDictionaryItem("Parent", expectedEnglishParentValue, "en-GB");
@@ -600,7 +600,7 @@ public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
// Act
var dictionaryItems =
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0);
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), Constants.Security.SuperUserId);
// Assert
Assert.That(await DictionaryItemService.ExistsAsync(parentKey), "DictionaryItem parentKey does not exist");
@@ -629,7 +629,7 @@ public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
await AddExistingEnglishAndNorwegianParentDictionaryItem(expectedEnglishParentValue, expectedNorwegianParentValue);
// Act
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0);
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), Constants.Security.SuperUserId);
// Assert
await AssertDictionaryItem("Parent", expectedEnglishParentValue, "en-GB");
@@ -654,7 +654,7 @@ public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
await AddExistingEnglishParentDictionaryItem(expectedEnglishParentValue);
// Act
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0);
PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), Constants.Security.SuperUserId);
// Assert
await AssertDictionaryItem("Parent", expectedEnglishParentValue, "en-GB");
@@ -671,7 +671,7 @@ public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
var languageItemsElement = newPackageXml.Elements("Languages").First();
// Act
var languages = PackageDataInstallation.ImportLanguages(languageItemsElement.Elements("Language"), 0);
var languages = PackageDataInstallation.ImportLanguages(languageItemsElement.Elements("Language"), Constants.Security.SuperUserId);
var allLanguages = await LanguageService.GetAllAsync();
// Assert

View File

@@ -147,13 +147,14 @@ public class DataTypeContainerServiceTests : UmbracoIntegrationTest
[Test]
public async Task Can_Delete_Child_Container()
{
Guid userKey = Constants.Security.SuperUserKey;
EntityContainer root = new EntityContainer(Constants.ObjectTypes.DataType) { Name = "Root Container" };
await DataTypeContainerService.CreateAsync(root, null, Constants.Security.SuperUserKey);
await DataTypeContainerService.CreateAsync(root, null, userKey);
EntityContainer child = new EntityContainer(Constants.ObjectTypes.DataType) { Name = "Child Container" };
await DataTypeContainerService.CreateAsync(child, null, root.Key);
await DataTypeContainerService.CreateAsync(child, root.Key, userKey);
var result = await DataTypeContainerService.DeleteAsync(child.Key, Constants.Security.SuperUserKey);
var result = await DataTypeContainerService.DeleteAsync(child.Key, userKey);
Assert.IsTrue(result.Success);
Assert.AreEqual(DataTypeContainerOperationStatus.Success, result.Status);

View File

@@ -3,6 +3,7 @@
using System.Diagnostics;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence;
@@ -207,7 +208,7 @@ public class LocalizationServiceTests : UmbracoIntegrationTest
var languageNbNo = new LanguageBuilder()
.WithCultureInfo("nb-NO")
.Build();
LocalizationService.Save(languageNbNo, 0);
LocalizationService.Save(languageNbNo, Constants.Security.SuperUserId);
Assert.That(languageNbNo.HasIdentity, Is.True);
var languageId = languageNbNo.Id;
@@ -225,7 +226,7 @@ public class LocalizationServiceTests : UmbracoIntegrationTest
.WithCultureInfo("nb-NO")
.WithFallbackLanguageIsoCode(languageDaDk.IsoCode)
.Build();
LocalizationService.Save(languageNbNo, 0);
LocalizationService.Save(languageNbNo, Constants.Security.SuperUserId);
var languageId = languageDaDk.Id;
LocalizationService.Delete(languageDaDk);
@@ -443,8 +444,8 @@ public class LocalizationServiceTests : UmbracoIntegrationTest
.WithCultureInfo("en-GB")
.Build();
LocalizationService.Save(languageDaDk, 0);
LocalizationService.Save(languageEnGb, 0);
LocalizationService.Save(languageDaDk, Constants.Security.SuperUserId);
LocalizationService.Save(languageEnGb, Constants.Security.SuperUserId);
_danishLangId = languageDaDk.Id;
_englishLangId = languageEnGb.Id;
@@ -472,4 +473,4 @@ public class LocalizationServiceTests : UmbracoIntegrationTest
_childItemGuidId = childItem.Key;
_childItemIntId = childItem.Id;
}
}
}

View File

@@ -61,16 +61,28 @@ public class UserIdKeyResolverTests : UmbracoIntegrationTest
}
[Test]
public async Task Unknown_Key_Resolves_To_Null()
public async Task Can_Resolve_Super_User_Key_To_Id()
{
var resolvedId = await UserIdKeyResolver.GetAsync(Guid.NewGuid());
Assert.IsNull(resolvedId);
var resolvedId = await UserIdKeyResolver.GetAsync(Constants.Security.SuperUserKey);
Assert.AreEqual(Constants.Security.SuperUserId, resolvedId);
}
[Test]
public async Task Unknown_Id_Resolves_To_Null()
public async Task Can_Resolve_Super_User_Id_To_Key()
{
var resolvedKey = await UserIdKeyResolver.GetAsync(1234567890);
Assert.IsNull(resolvedKey);
var resolvedKey = await UserIdKeyResolver.GetAsync(Constants.Security.SuperUserId);
Assert.AreEqual(Constants.Security.SuperUserKey, resolvedKey);
}
[Test]
public async Task Unknown_Key_Throws()
{
Assert.ThrowsAsync<InvalidOperationException>(async () => await UserIdKeyResolver.GetAsync(Guid.NewGuid()));
}
[Test]
public async Task Unknown_Id_Throws()
{
Assert.ThrowsAsync<InvalidOperationException>(async () => await UserIdKeyResolver.GetAsync(1234567890));
}
}