Members and member types in the Management API (#15662)

* Members and member types in the Management API

* Add validation endpoints for members

* Include validation result in service response + add unit tests

* Regenerate OpenApi.json

* Regenerate OpenApi.json after merge

* Don't throw an exception when trying to set valid variation levels for member types

* Added missing ProducesResponseType

* Remove TODO, as that works

* Allow creation of member with explicit key

* Do not feature "parent" for member creation + add missing response type

* Do not feature a "Folder" in create member type (folders are not supported)

* Added missing build methods

* Fixed issue with mapping

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
Kenn Jacobsen
2024-02-05 06:42:07 +01:00
committed by GitHub
parent dde2ccfd41
commit 71b3076de9
101 changed files with 4354 additions and 124 deletions

View File

@@ -315,7 +315,7 @@ namespace Umbraco.Cms.Core.Services
/// and the user id in the membership provider.</remarks>
/// <param name="id"><see cref="Guid"/> Id</param>
/// <returns><see cref="IMember"/></returns>
public IMember? GetByKey(Guid id)
public IMember? GetById(Guid id)
{
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
scope.ReadLock(Constants.Locks.MemberTree);
@@ -323,6 +323,10 @@ namespace Umbraco.Cms.Core.Services
return _memberRepository.Get(query)?.FirstOrDefault();
}
[Obsolete($"Use {nameof(GetById)}. Will be removed in V15.")]
public IMember? GetByKey(Guid id)
=> GetById(id);
/// <summary>
/// Gets a list of paged <see cref="IMember"/> objects
/// </summary>
@@ -745,7 +749,7 @@ namespace Umbraco.Cms.Core.Services
public void SetLastLogin(string username, DateTime date) => throw new NotImplementedException();
/// <inheritdoc />
public void Save(IMember member)
public Attempt<OperationResult?> Save(IMember member, int userId = Constants.Security.SuperUserId)
{
// trimming username and email to make sure we have no trailing space
member.Username = member.Username.Trim();
@@ -758,7 +762,7 @@ namespace Umbraco.Cms.Core.Services
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
return OperationResult.Attempt.Cancel(evtMsgs);
}
if (string.IsNullOrWhiteSpace(member.Name))
@@ -775,10 +779,14 @@ namespace Umbraco.Cms.Core.Services
Audit(AuditType.Save, 0, member.Id);
scope.Complete();
return OperationResult.Attempt.Succeed(evtMsgs);
}
public void Save(IMember member)
=> Save(member, Constants.Security.SuperUserId);
/// <inheritdoc />
public void Save(IEnumerable<IMember> members)
public Attempt<OperationResult?> Save(IEnumerable<IMember> members, int userId = Constants.Security.SuperUserId)
{
IMember[] membersA = members.ToArray();
@@ -789,7 +797,7 @@ namespace Umbraco.Cms.Core.Services
if (scope.Notifications.PublishCancelable(savingNotification))
{
scope.Complete();
return;
return OperationResult.Attempt.Cancel(evtMsgs);
}
scope.WriteLock(Constants.Locks.MemberTree);
@@ -805,20 +813,22 @@ namespace Umbraco.Cms.Core.Services
scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification));
Audit(AuditType.Save, 0, -1, "Save multiple Members");
Audit(AuditType.Save, userId, Constants.System.Root, "Save multiple Members");
scope.Complete();
return OperationResult.Attempt.Succeed(evtMsgs);
}
[Obsolete($"Use the {nameof(Save)} method that yields an Attempt. Will be removed in V15.")]
public void Save(IEnumerable<IMember> members)
=> Save(members, Constants.Security.SuperUserId);
#endregion
#region Delete
/// <summary>
/// Deletes an <see cref="IMember"/>
/// </summary>
/// <param name="member"><see cref="IMember"/> to Delete</param>
public void Delete(IMember member)
/// <inheritdoc />
public Attempt<OperationResult?> Delete(IMember member, int userId = Constants.Security.SuperUserId)
{
EventMessages evtMsgs = EventMessagesFactory.Get();
@@ -827,7 +837,7 @@ namespace Umbraco.Cms.Core.Services
if (scope.Notifications.PublishCancelable(deletingNotification))
{
scope.Complete();
return;
return OperationResult.Attempt.Cancel(evtMsgs);
}
scope.WriteLock(Constants.Locks.MemberTree);
@@ -835,8 +845,14 @@ namespace Umbraco.Cms.Core.Services
Audit(AuditType.Delete, 0, member.Id);
scope.Complete();
return OperationResult.Attempt.Succeed(evtMsgs);
}
/// <inheritdoc />
public void Delete(IMember member)
=> Delete(member, Constants.Security.SuperUserId);
private void DeleteLocked(ICoreScope scope, IMember member, EventMessages evtMsgs, IDictionary<string, object?>? notificationState = null)
{
// a member has no descendants
@@ -1025,6 +1041,16 @@ namespace Umbraco.Cms.Core.Services
#endregion
#region Others
// NOTE: at the time of writing we do not have MemberTreeChangeNotification to publish changes as a result of a data integrity
// check. we cannot support this feature until such notification exists.
// see the content or media services for implementation details if this is ever going to be a relevant feature for members.
public ContentDataIntegrityReport CheckDataIntegrity(ContentDataIntegrityReportOptions options)
=> throw new InvalidOperationException("Data integrity checks are not (yet) implemented for members.");
#endregion
#region Private Methods
private void Audit(AuditType type, int userId, int objectId, string? message = null) => _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.Member), message));