using System.ComponentModel; using Microsoft.AspNetCore.Identity; using Umbraco.Cms.Core.Models.Entities; namespace Umbraco.Cms.Core.Security; public class UmbracoIdentityRole : IdentityRole, IRememberBeingDirty { private string _id = string.Empty; private string _name = string.Empty; public UmbracoIdentityRole(string roleName) : base(roleName) { } public UmbracoIdentityRole() { } public event PropertyChangedEventHandler PropertyChanged { add => BeingDirty.PropertyChanged += value; remove => BeingDirty.PropertyChanged -= value; } /// public override string Id { get => _id; set { _id = value; HasIdentity = true; } } /// public override string? Name { get => _name; set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _name!, nameof(Name)); } /// public override string? NormalizedName { get => base.Name ?? string.Empty; set => base.Name = value; } /// /// Gets or sets a value indicating whether returns an Id has been set on this object this will be false if the object /// is new and not persisted to the database /// public bool HasIdentity { get; protected set; } // NOTE: The purpose // of this value is to try to prevent concurrent writes in the DB but this is // an implementation detail at the data source level that has leaked into the // model. A good writeup of that is here: // https://stackoverflow.com/a/37362173 // For our purposes currently we won't worry about this. public override string? ConcurrencyStamp { get => base.ConcurrencyStamp; set => base.ConcurrencyStamp = value; } /// /// Gets the for change tracking /// protected BeingDirty BeingDirty { get; } = new(); /// public bool IsDirty() => BeingDirty.IsDirty(); /// public bool IsPropertyDirty(string propName) => BeingDirty.IsPropertyDirty(propName); /// public IEnumerable GetDirtyProperties() => BeingDirty.GetDirtyProperties(); /// public void ResetDirtyProperties() => BeingDirty.ResetDirtyProperties(); /// public bool WasDirty() => BeingDirty.WasDirty(); /// public bool WasPropertyDirty(string propertyName) => BeingDirty.WasPropertyDirty(propertyName); /// public void ResetWereDirtyProperties() => BeingDirty.ResetWereDirtyProperties(); /// public void ResetDirtyProperties(bool rememberDirty) => BeingDirty.ResetDirtyProperties(rememberDirty); /// public IEnumerable GetWereDirtyProperties() => BeingDirty.GetWereDirtyProperties(); /// /// Disables change tracking. /// public void DisableChangeTracking() => BeingDirty.DisableChangeTracking(); /// /// Enables change tracking. /// public void EnableChangeTracking() => BeingDirty.EnableChangeTracking(); }