diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index eeaf7533a9..4761f2a1fc 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -137,6 +137,7 @@ namespace Umbraco.Core.Migrations.Upgrade // resume at {290C18EE-B3DE-4769-84F1-1F467F3F76DA}... Chain("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}"); + Chain("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}"); //FINAL diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLogTableColumns.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLogTableColumns.cs new file mode 100644 index 0000000000..d038da2573 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLogTableColumns.cs @@ -0,0 +1,24 @@ +using System.Linq; +using Umbraco.Core.Persistence.Dtos; + +namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 +{ + public class AddLogTableColumns : MigrationBase + { + public AddLogTableColumns(IMigrationContext context) + : base(context) + { } + + public override void Migrate() + { + var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList(); + + if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.Log) && !x.ColumnName.InvariantEquals("entityType"))) + AddColumn("entityType"); + + if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.Log) && !x.ColumnName.InvariantEquals("parameters"))) + AddColumn("parameters"); + + } + } +} diff --git a/src/Umbraco.Core/Models/AuditItem.cs b/src/Umbraco.Core/Models/AuditItem.cs index 6bfe32bd77..483548f558 100644 --- a/src/Umbraco.Core/Models/AuditItem.cs +++ b/src/Umbraco.Core/Models/AuditItem.cs @@ -11,7 +11,7 @@ namespace Umbraco.Core.Models /// /// /// - public AuditItem(int objectId, string comment, AuditType type, int userId) + public AuditItem(int objectId, AuditType type, int userId, string entityType, string comment = null, string parameters = null) { DisableChangeTracking(); @@ -19,11 +19,19 @@ namespace Umbraco.Core.Models Comment = comment; AuditType = type; UserId = userId; + EntityType = entityType; + Parameters = parameters; EnableChangeTracking(); } public string Comment { get; } + + /// + public string EntityType { get; } + /// + public string Parameters { get; } + public AuditType AuditType { get; } public int UserId { get; } } diff --git a/src/Umbraco.Core/Persistence/Dtos/LogDto.cs b/src/Umbraco.Core/Persistence/Dtos/LogDto.cs index 2ecf85e87c..a362d5d50c 100644 --- a/src/Umbraco.Core/Persistence/Dtos/LogDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/LogDto.cs @@ -25,10 +25,20 @@ namespace Umbraco.Core.Persistence.Dtos [Index(IndexTypes.NonClustered, Name = "IX_umbracoLog")] public int NodeId { get; set; } + /// + /// This is the entity type associated with the log + /// + [Column("entityType")] + [Length(50)] + [NullSetting(NullSetting = NullSettings.Null)] + public string EntityType { get; set; } + + //TODO: Should we have an index on this since we allow searching on it? [Column("Datestamp")] [Constraint(Default = SystemMethods.CurrentDateTime)] public DateTime Datestamp { get; set; } + //TODO: Should we have an index on this since we allow searching on it? [Column("logHeader")] [Length(50)] public string Header { get; set; } @@ -37,5 +47,13 @@ namespace Umbraco.Core.Persistence.Dtos [NullSetting(NullSetting = NullSettings.Null)] [Length(4000)] public string Comment { get; set; } + + /// + /// Used to store additional data parameters for the log + /// + [Column("parameters")] + [NullSetting(NullSetting = NullSettings.Null)] + [Length(500)] + public string Parameters { get; set; } } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs index 5d386d9cb4..6c61fe7ad5 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs @@ -28,20 +28,24 @@ namespace Umbraco.Core.Persistence.Repositories.Implement Datestamp = DateTime.Now, Header = entity.AuditType.ToString(), NodeId = entity.Id, - UserId = entity.UserId + UserId = entity.UserId, + EntityType = entity.EntityType, + Parameters = entity.Parameters }); } protected override void PersistUpdatedItem(IAuditItem entity) { - // wtf?! inserting when updating?! + // inserting when updating because we never update a log entry, perhaps this should throw? Database.Insert(new LogDto { Comment = entity.Comment, Datestamp = DateTime.Now, Header = entity.AuditType.ToString(), NodeId = entity.Id, - UserId = entity.UserId + UserId = entity.UserId, + EntityType = entity.EntityType, + Parameters = entity.Parameters }); } @@ -53,7 +57,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var dto = Database.First(sql); return dto == null ? null - : new AuditItem(dto.NodeId, dto.Comment, Enum.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId); + : new AuditItem(dto.NodeId, Enum.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters); } protected override IEnumerable PerformGetAll(params int[] ids) @@ -69,7 +73,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var dtos = Database.Fetch(sql); - return dtos.Select(x => new AuditItem(x.NodeId, x.Comment, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId)).ToArray(); + return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList(); } protected override Sql GetBaseQuery(bool isCount) @@ -160,10 +164,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement totalRecords = page.TotalItems; var items = page.Items.Select( - dto => new AuditItem(dto.Id, dto.Comment, Enum.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId)).ToArray(); + dto => new AuditItem(dto.Id, Enum.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters)).ToList(); // map the DateStamp - for (var i = 0; i < items.Length; i++) + for (var i = 0; i < items.Count; i++) items[i].CreateDate = page.Items[i].Datestamp; return items; diff --git a/src/Umbraco.Core/Services/IAuditService.cs b/src/Umbraco.Core/Services/IAuditService.cs index 13d84f802e..f9b5aa2d87 100644 --- a/src/Umbraco.Core/Services/IAuditService.cs +++ b/src/Umbraco.Core/Services/IAuditService.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Services /// public interface IAuditService : IService { - void Add(AuditType type, string comment, int userId, int objectId); + void Add(AuditType type, int userId, int objectId, string entityType, string comment, string parameters = null); IEnumerable GetLogs(int objectId); IEnumerable GetUserLogs(int userId, AuditType type, DateTime? sinceDate = null); diff --git a/src/Umbraco.Core/Services/Implement/AuditService.cs b/src/Umbraco.Core/Services/Implement/AuditService.cs index 389a2337d1..d02d7f541b 100644 --- a/src/Umbraco.Core/Services/Implement/AuditService.cs +++ b/src/Umbraco.Core/Services/Implement/AuditService.cs @@ -27,11 +27,11 @@ namespace Umbraco.Core.Services.Implement _isAvailable = new Lazy(DetermineIsAvailable); } - public void Add(AuditType type, string comment, int userId, int objectId) + public void Add(AuditType type, int userId, int objectId, string entityType, string comment, string parameters = null) { using (var scope = ScopeProvider.CreateScope()) { - _auditRepository.Save(new AuditItem(objectId, comment, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, entityType, comment, parameters)); scope.Complete(); } } diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index a849813b13..c4b17e1350 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -328,7 +328,7 @@ namespace Umbraco.Core.Services.Implement if (withIdentity == false) return; - Audit(AuditType.New, $"Content '{content.Name}' was created with Id {content.Id}", content.CreatorId, content.Id); + Audit(AuditType.New, content.CreatorId, content.Id, $"Content '{content.Name}' was created with Id {content.Id}"); } #endregion @@ -843,7 +843,16 @@ namespace Umbraco.Core.Services.Implement } var changeType = TreeChangeTypes.RefreshNode; scope.Events.Dispatch(TreeChanged, this, new TreeChange(content, changeType).ToEventArgs()); - Audit(AuditType.Save, "Saved by user", userId, content.Id); + + var culturesChanging = content.ContentType.VariesByCulture() + ? content.CultureNames.Where(x => x.IsDirty()).Select(x => x.Culture).ToList() + : null; + + if (culturesChanging != null && culturesChanging.Count > 0) + Audit(AuditType.Save, userId, content.Id, $"Saved culture{(culturesChanging.Count > 1 ? "s" : string.Empty)} {string.Join(",", culturesChanging)}"); + else + Audit(AuditType.Save, userId, content.Id); + scope.Complete(); } @@ -883,7 +892,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Saved, this, saveEventArgs, "Saved"); } scope.Events.Dispatch(TreeChanged, this, treeChanges.ToEventArgs()); - Audit(AuditType.Save, "Bulk-saved by user", userId == -1 ? 0 : userId, Constants.System.Root); + Audit(AuditType.Save, userId == -1 ? 0 : userId, Constants.System.Root, "Saved multiple content"); scope.Complete(); } @@ -988,14 +997,14 @@ namespace Umbraco.Core.Services.Implement UnpublishResultType result; if (culture == "*" || culture == null) { - Audit(AuditType.Unpublish, "Unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, userId, content.Id); result = UnpublishResultType.Success; } else { - Audit(AuditType.Unpublish, $"Culture \"{culture}\" unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, userId, content.Id, $"Culture \"{culture}\" unpublished"); if (!content.Published) - Audit(AuditType.Unpublish, $"Unpublished (culture \"{culture}\" is mandatory) by user", userId, content.Id); + Audit(AuditType.Unpublish, userId, content.Id, $"Unpublished (culture \"{culture}\" is mandatory)"); result = content.Published ? UnpublishResultType.SuccessCulture : UnpublishResultType.SuccessMandatoryCulture; } scope.Complete(); @@ -1025,6 +1034,8 @@ namespace Umbraco.Core.Services.Implement var publishing = content.PublishedState == PublishedState.Publishing; var unpublishing = content.PublishedState == PublishedState.Unpublishing; + List culturesChanging = null; + using (var scope = ScopeProvider.CreateScope()) { // is the content going to end up published, or unpublished? @@ -1046,6 +1057,10 @@ namespace Umbraco.Core.Services.Implement // we may end up in a state where we won't publish nor unpublish // keep going, though, as we want to save anways } + else + { + culturesChanging = content.PublishNames.Where(x => x.IsDirty()).Select(x => x.Culture).ToList(); + } } var isNew = !content.HasIdentity; @@ -1085,6 +1100,7 @@ namespace Umbraco.Core.Services.Implement // ensure that the document can be unpublished, and unpublish // handling events, business rules, etc // note: StrategyUnpublish flips the PublishedState to Unpublishing! + // note: This unpublishes the entire document (not different variants) unpublishResult = StrategyCanUnpublish(scope, content, userId, evtMsgs); if (unpublishResult.Success) unpublishResult = StrategyUnpublish(scope, content, true, userId, evtMsgs); @@ -1122,7 +1138,7 @@ namespace Umbraco.Core.Services.Implement // events and audit scope.Events.Dispatch(Unpublished, this, new PublishEventArgs(content, false, false), "Unpublished"); scope.Events.Dispatch(TreeChanged, this, new TreeChange(content, TreeChangeTypes.RefreshBranch).ToEventArgs()); - Audit(AuditType.Unpublish, "Unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, userId, content.Id); scope.Complete(); return new PublishResult(PublishResultType.Success, evtMsgs, content); } @@ -1153,7 +1169,11 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Published, this, new PublishEventArgs(descendants, false, false), "Published"); } - Audit(AuditType.Publish, "Published by user", userId, content.Id); + if (culturesChanging != null && culturesChanging.Count > 0) + Audit(AuditType.Publish, userId, content.Id, $"Published culture{(culturesChanging.Count > 1 ? "s" : string.Empty)} {string.Join(",", culturesChanging)}"); + else + Audit(AuditType.Publish, userId, content.Id); + scope.Complete(); return publishResult; } @@ -1264,6 +1284,8 @@ namespace Umbraco.Core.Services.Implement // deal with descendants // if one fails, abort its branch var exclude = new HashSet(); + + //fixme: should be paged to not overwhelm the database (timeouts) foreach (var d in GetDescendants(document)) { // if parent is excluded, exclude document and ignore @@ -1287,7 +1309,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(TreeChanged, this, new TreeChange(document, TreeChangeTypes.RefreshBranch).ToEventArgs()); scope.Events.Dispatch(Published, this, new PublishEventArgs(publishedDocuments, false, false), "Published"); - Audit(AuditType.Publish, "Branch published by user", userId, document.Id); + Audit(AuditType.Publish, userId, document.Id, "Branch published"); scope.Complete(); } @@ -1356,7 +1378,7 @@ namespace Umbraco.Core.Services.Implement DeleteLocked(scope, content); scope.Events.Dispatch(TreeChanged, this, new TreeChange(content, TreeChangeTypes.Remove).ToEventArgs()); - Audit(AuditType.Delete, "Deleted by user", userId, content.Id); + Audit(AuditType.Delete, userId, content.Id); scope.Complete(); } @@ -1424,7 +1446,7 @@ namespace Umbraco.Core.Services.Implement deleteRevisionsEventArgs.CanCancel = false; scope.Events.Dispatch(DeletedVersions, this, deleteRevisionsEventArgs); - Audit(AuditType.Delete, "Delete (by version date) by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, "Delete (by version date)"); scope.Complete(); } @@ -1461,7 +1483,7 @@ namespace Umbraco.Core.Services.Implement _documentRepository.DeleteVersion(versionId); scope.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false,/* specificVersion:*/ versionId)); - Audit(AuditType.Delete, "Delete (by version) by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, "Delete (by version)"); scope.Complete(); } @@ -1506,7 +1528,7 @@ namespace Umbraco.Core.Services.Implement moveEventArgs.CanCancel = false; moveEventArgs.MoveInfoCollection = moveInfo; scope.Events.Dispatch(Trashed, this, moveEventArgs, nameof(Trashed)); - Audit(AuditType.Move, "Moved to Recycle Bin by user", userId, content.Id); + Audit(AuditType.Move, userId, content.Id, "Moved to recycle bin"); scope.Complete(); } @@ -1578,7 +1600,7 @@ namespace Umbraco.Core.Services.Implement moveEventArgs.MoveInfoCollection = moveInfo; moveEventArgs.CanCancel = false; scope.Events.Dispatch(Moved, this, moveEventArgs, nameof(Moved)); - Audit(AuditType.Move, "Moved by user", userId, content.Id); + Audit(AuditType.Move, userId, content.Id); scope.Complete(); } @@ -1675,7 +1697,7 @@ namespace Umbraco.Core.Services.Implement recycleBinEventArgs.RecycleBinEmptiedSuccessfully = true; // oh my?! scope.Events.Dispatch(EmptiedRecycleBin, this, recycleBinEventArgs); scope.Events.Dispatch(TreeChanged, this, deleted.Select(x => new TreeChange(x, TreeChangeTypes.Remove)).ToEventArgs()); - Audit(AuditType.Delete, "Recycle Bin emptied by user", 0, Constants.System.RecycleBinContent); + Audit(AuditType.Delete, 0, Constants.System.RecycleBinContent, "Recycle bin emptied"); scope.Complete(); } @@ -1793,7 +1815,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(TreeChanged, this, new TreeChange(copy, TreeChangeTypes.RefreshBranch).ToEventArgs()); foreach (var x in copies) scope.Events.Dispatch(Copied, this, new CopyEventArgs(x.Item1, x.Item2, false, x.Item2.ParentId, relateToOriginal)); - Audit(AuditType.Copy, "Copy Content performed by user", userId, content.Id); + Audit(AuditType.Copy, userId, content.Id); scope.Complete(); } @@ -1824,7 +1846,15 @@ namespace Umbraco.Core.Services.Implement sendToPublishEventArgs.CanCancel = false; scope.Events.Dispatch(SentToPublish, this, sendToPublishEventArgs); - Audit(AuditType.SendToPublish, "Send to Publish performed by user", content.WriterId, content.Id); + + var culturesChanging = content.ContentType.VariesByCulture() + ? content.CultureNames.Where(x => x.IsDirty()).Select(x => x.Culture).ToList() + : null; + + if (culturesChanging != null && culturesChanging.Count > 0) + Audit(AuditType.SendToPublish, userId, content.Id, $"Send To Publish for culture{(culturesChanging.Count > 1 ? "s" : string.Empty)} {string.Join(",", culturesChanging)}"); + else + Audit(AuditType.SendToPublish, content.WriterId, content.Id); } return true; @@ -1930,7 +1960,7 @@ namespace Umbraco.Core.Services.Implement if (raiseEvents && published.Any()) scope.Events.Dispatch(Published, this, new PublishEventArgs(published, false, false), "Published"); - Audit(AuditType.Sort, "Sorting content performed by user", userId, 0); + Audit(AuditType.Sort, userId, 0); return true; } @@ -1977,9 +2007,9 @@ namespace Umbraco.Core.Services.Implement #region Private Methods - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId, string message = null) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, Constants.ObjectTypes.Strings.Document, message)); } #endregion @@ -2311,7 +2341,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, moveInfos), nameof(Trashed)); scope.Events.Dispatch(TreeChanged, this, changes.ToEventArgs()); - Audit(AuditType.Delete, $"Delete Content of Type {string.Join(",", contentTypeIdsA)} performed by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, $"Delete content of type {string.Join(",", contentTypeIdsA)}"); scope.Complete(); } diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs index a114f415cc..60677cfd81 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs @@ -423,7 +423,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; OnSaved(scope, saveEventArgs); - Audit(AuditType.Save, $"Save {typeof(TItem).Name} performed by user", userId, item.Id); + Audit(AuditType.Save, userId, item.Id); scope.Complete(); } } @@ -465,7 +465,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; OnSaved(scope, saveEventArgs); - Audit(AuditType.Save, $"Save {typeof(TItem).Name} performed by user", userId, -1); + Audit(AuditType.Save, userId, -1); scope.Complete(); } } @@ -523,7 +523,7 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; OnDeleted(scope, deleteEventArgs); - Audit(AuditType.Delete, $"Delete {typeof(TItem).Name} performed by user", userId, item.Id); + Audit(AuditType.Delete, userId, item.Id); scope.Complete(); } } @@ -576,7 +576,7 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; OnDeleted(scope, deleteEventArgs); - Audit(AuditType.Delete, $"Delete {typeof(TItem).Name} performed by user", userId, -1); + Audit(AuditType.Delete, userId, -1); scope.Complete(); } } @@ -963,9 +963,10 @@ namespace Umbraco.Core.Services.Implement #region Audit - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, + ObjectTypes.GetUmbracoObjectType(ContainedObjectType).GetName())); } #endregion diff --git a/src/Umbraco.Core/Services/Implement/DataTypeService.cs b/src/Umbraco.Core/Services/Implement/DataTypeService.cs index c105b6cfe6..79ca851de9 100644 --- a/src/Umbraco.Core/Services/Implement/DataTypeService.cs +++ b/src/Umbraco.Core/Services/Implement/DataTypeService.cs @@ -353,7 +353,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); - Audit(AuditType.Save, "Save DataTypeDefinition performed by user", userId, dataType.Id); + Audit(AuditType.Save, userId, dataType.Id); scope.Complete(); } } @@ -398,7 +398,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); } - Audit(AuditType.Save, "Save DataTypeDefinition performed by user", userId, -1); + Audit(AuditType.Save, userId, -1); scope.Complete(); } @@ -456,15 +456,15 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; scope.Events.Dispatch(Deleted, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete DataTypeDefinition performed by user", userId, dataType.Id); + Audit(AuditType.Delete, userId, dataType.Id); scope.Complete(); } } - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.DataType))); } #region Event Handlers diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index c3a8b790cc..f15f0d7d47 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -91,7 +91,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(SavedStylesheet, this, saveEventArgs); - Audit(AuditType.Save, "Save Stylesheet performed by user", userId, -1); + Audit(AuditType.Save, userId, -1, ObjectTypes.GetName(UmbracoObjectTypes.Stylesheet)); scope.Complete(); } } @@ -123,7 +123,7 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; scope.Events.Dispatch(DeletedStylesheet, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete Stylesheet performed by user", userId, -1); + Audit(AuditType.Delete, userId, -1, ObjectTypes.GetName(UmbracoObjectTypes.Stylesheet)); scope.Complete(); } } @@ -215,7 +215,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(SavedScript, this, saveEventArgs); - Audit(AuditType.Save, "Save Script performed by user", userId, -1); + Audit(AuditType.Save, userId, -1, "Script"); scope.Complete(); } } @@ -247,7 +247,7 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; scope.Events.Dispatch(DeletedScript, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete Script performed by user", userId, -1); + Audit(AuditType.Delete, userId, -1, "Script"); scope.Complete(); } } @@ -362,7 +362,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(SavedTemplate, this, saveEventArgs); - Audit(AuditType.Save, "Save Template performed by user", userId, template.Id); + Audit(AuditType.Save, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } @@ -525,7 +525,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(SavedTemplate, this, new SaveEventArgs(template, false)); - Audit(AuditType.Save, "Save Template performed by user", userId, template.Id); + Audit(AuditType.Save, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } } @@ -551,7 +551,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(SavedTemplate, this, new SaveEventArgs(templatesA, false)); - Audit(AuditType.Save, "Save Template performed by user", userId, -1); + Audit(AuditType.Save, userId, -1, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } } @@ -605,7 +605,7 @@ namespace Umbraco.Core.Services.Implement args.CanCancel = false; scope.Events.Dispatch(DeletedTemplate, this, args); - Audit(AuditType.Delete, "Delete Template performed by user", userId, template.Id); + Audit(AuditType.Delete, userId, template.Id, ObjectTypes.GetName(UmbracoObjectTypes.Template)); scope.Complete(); } } @@ -788,7 +788,7 @@ namespace Umbraco.Core.Services.Implement newEventArgs.CanCancel = false; scope.Events.Dispatch(CreatedPartialView, this, newEventArgs); - Audit(AuditType.Save, $"Save {partialViewType} performed by user", userId, -1); + Audit(AuditType.Save, userId, -1, partialViewType.ToString()); scope.Complete(); } @@ -828,7 +828,7 @@ namespace Umbraco.Core.Services.Implement repository.Delete(partialView); deleteEventArgs.CanCancel = false; scope.Events.Dispatch(DeletedPartialView, this, deleteEventArgs); - Audit(AuditType.Delete, $"Delete {partialViewType} performed by user", userId, -1); + Audit(AuditType.Delete, userId, -1, partialViewType.ToString()); scope.Complete(); } @@ -860,7 +860,7 @@ namespace Umbraco.Core.Services.Implement var repository = GetPartialViewRepository(partialViewType); repository.Save(partialView); saveEventArgs.CanCancel = false; - Audit(AuditType.Save, $"Save {partialViewType} performed by user", userId, -1); + Audit(AuditType.Save, userId, -1, partialViewType.ToString()); scope.Events.Dispatch(SavedPartialView, this, saveEventArgs); scope.Complete(); @@ -1038,9 +1038,9 @@ namespace Umbraco.Core.Services.Implement #endregion - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId, string entityType) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, entityType)); } //TODO Method to change name and/or alias of view/masterpage template diff --git a/src/Umbraco.Core/Services/Implement/LocalizationService.cs b/src/Umbraco.Core/Services/Implement/LocalizationService.cs index 49a764b533..c972b949d6 100644 --- a/src/Umbraco.Core/Services/Implement/LocalizationService.cs +++ b/src/Umbraco.Core/Services/Implement/LocalizationService.cs @@ -245,7 +245,7 @@ namespace Umbraco.Core.Services.Implement EnsureDictionaryItemLanguageCallback(dictionaryItem); scope.Events.Dispatch(SavedDictionaryItem, this, new SaveEventArgs(dictionaryItem, false)); - Audit(AuditType.Save, "Save DictionaryItem performed by user", userId, dictionaryItem.Id); + Audit(AuditType.Save, "Save DictionaryItem", userId, dictionaryItem.Id, "DictionaryItem"); scope.Complete(); } } @@ -271,7 +271,7 @@ namespace Umbraco.Core.Services.Implement deleteEventArgs.CanCancel = false; scope.Events.Dispatch(DeletedDictionaryItem, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete DictionaryItem performed by user", userId, dictionaryItem.Id); + Audit(AuditType.Delete, "Delete DictionaryItem", userId, dictionaryItem.Id, "DictionaryItem"); scope.Complete(); } @@ -384,7 +384,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(SavedLanguage, this, saveEventArgs); - Audit(AuditType.Save, "Save Language performed by user", userId, language.Id); + Audit(AuditType.Save, "Save Language", userId, language.Id, ObjectTypes.GetName(UmbracoObjectTypes.Language)); scope.Complete(); } @@ -429,14 +429,14 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(DeletedLanguage, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete Language performed by user", userId, language.Id); + Audit(AuditType.Delete, "Delete Language", userId, language.Id, ObjectTypes.GetName(UmbracoObjectTypes.Language)); scope.Complete(); } } - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, string message, int userId, int objectId, string entityType) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, entityType, message)); } /// diff --git a/src/Umbraco.Core/Services/Implement/MacroService.cs b/src/Umbraco.Core/Services/Implement/MacroService.cs index fdcc8e2ee0..5176e2eb22 100644 --- a/src/Umbraco.Core/Services/Implement/MacroService.cs +++ b/src/Umbraco.Core/Services/Implement/MacroService.cs @@ -95,7 +95,7 @@ namespace Umbraco.Core.Services.Implement _macroRepository.Delete(macro); deleteEventArgs.CanCancel = false; scope.Events.Dispatch(Deleted, this, deleteEventArgs); - Audit(AuditType.Delete, "Delete Macro performed by user", userId, -1); + Audit(AuditType.Delete, userId, -1); scope.Complete(); } @@ -125,7 +125,7 @@ namespace Umbraco.Core.Services.Implement _macroRepository.Save(macro); saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); - Audit(AuditType.Save, "Save Macro performed by user", userId, -1); + Audit(AuditType.Save, userId, -1); scope.Complete(); } @@ -150,9 +150,9 @@ namespace Umbraco.Core.Services.Implement // return MacroPropertyTypeResolver.Current.MacroPropertyTypes.FirstOrDefault(x => x.Alias == alias); //} - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, "Macro")); } #region Event Handlers diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index 431e20044c..da04f41e18 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -295,7 +295,7 @@ namespace Umbraco.Core.Services.Implement if (withIdentity == false) return; - Audit(AuditType.New, $"Media '{media.Name}' was created with Id {media.Id}", media.CreatorId, media.Id); + Audit(AuditType.New, media.CreatorId, media.Id, $"Media '{media.Name}' was created with Id {media.Id}"); } #endregion @@ -778,7 +778,7 @@ namespace Umbraco.Core.Services.Implement var changeType = TreeChangeTypes.RefreshNode; scope.Events.Dispatch(TreeChanged, this, new TreeChange(media, changeType).ToEventArgs()); - Audit(AuditType.Save, "Save Media performed by user", userId, media.Id); + Audit(AuditType.Save, userId, media.Id); scope.Complete(); } @@ -821,7 +821,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Saved, this, saveEventArgs); } scope.Events.Dispatch(TreeChanged, this, treeChanges.ToEventArgs()); - Audit(AuditType.Save, "Bulk Save media performed by user", userId == -1 ? 0 : userId, Constants.System.Root); + Audit(AuditType.Save, userId == -1 ? 0 : userId, Constants.System.Root, "Bulk save media"); scope.Complete(); } @@ -855,7 +855,7 @@ namespace Umbraco.Core.Services.Implement DeleteLocked(scope, media); scope.Events.Dispatch(TreeChanged, this, new TreeChange(media, TreeChangeTypes.Remove).ToEventArgs()); - Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id); + Audit(AuditType.Delete, userId, media.Id); scope.Complete(); } @@ -924,7 +924,7 @@ namespace Umbraco.Core.Services.Implement //repository.DeleteVersions(id, versionDate); //uow.Events.Dispatch(DeletedVersions, this, new DeleteRevisionsEventArgs(id, false, dateToRetain: versionDate)); - //Audit(uow, AuditType.Delete, "Delete Media by version date performed by user", userId, Constants.System.Root); + //Audit(uow, AuditType.Delete, "Delete Media by version date, userId, Constants.System.Root); //uow.Complete(); } @@ -942,7 +942,7 @@ namespace Umbraco.Core.Services.Implement args.CanCancel = false; scope.Events.Dispatch(DeletedVersions, this, args); - Audit(AuditType.Delete, "Delete Media by version date performed by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, "Delete Media by version date"); } /// @@ -978,7 +978,7 @@ namespace Umbraco.Core.Services.Implement args.CanCancel = false; scope.Events.Dispatch(DeletedVersions, this, args); - Audit(AuditType.Delete, "Delete Media by version performed by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, "Delete Media by version"); scope.Complete(); } @@ -1020,7 +1020,7 @@ namespace Umbraco.Core.Services.Implement .ToArray(); scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, evtMsgs, moveInfo), nameof(Trashed)); - Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id); + Audit(AuditType.Move, userId, media.Id, "Move Media to recycle bin"); scope.Complete(); } @@ -1080,7 +1080,7 @@ namespace Umbraco.Core.Services.Implement moveEventArgs.MoveInfoCollection = moveInfo; moveEventArgs.CanCancel = false; scope.Events.Dispatch(Moved, this, moveEventArgs, nameof(Moved)); - Audit(AuditType.Move, "Move Media performed by user", userId, media.Id); + Audit(AuditType.Move, userId, media.Id); scope.Complete(); } } @@ -1173,7 +1173,7 @@ namespace Umbraco.Core.Services.Implement args.CanCancel = false; scope.Events.Dispatch(EmptiedRecycleBin, this, args); scope.Events.Dispatch(TreeChanged, this, deleted.Select(x => new TreeChange(x, TreeChangeTypes.Remove)).ToEventArgs()); - Audit(AuditType.Delete, "Empty Media Recycle Bin performed by user", 0, Constants.System.RecycleBinMedia); + Audit(AuditType.Delete, 0, Constants.System.RecycleBinMedia, "Empty Media recycle bin"); scope.Complete(); } @@ -1238,7 +1238,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Saved, this, args); } scope.Events.Dispatch(TreeChanged, this, saved.Select(x => new TreeChange(x, TreeChangeTypes.RefreshNode)).ToEventArgs()); - Audit(AuditType.Sort, "Sorting Media performed by user", userId, 0); + Audit(AuditType.Sort, userId, 0); scope.Complete(); } @@ -1250,9 +1250,9 @@ namespace Umbraco.Core.Services.Implement #region Private Methods - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId, string message = null) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.Media), message)); } #endregion @@ -1434,7 +1434,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, moveInfos), nameof(Trashed)); scope.Events.Dispatch(TreeChanged, this, changes.ToEventArgs()); - Audit(AuditType.Delete, $"Delete Media of types {string.Join(",", mediaTypeIdsA)} performed by user", userId, Constants.System.Root); + Audit(AuditType.Delete, userId, Constants.System.Root, $"Delete Media of types {string.Join(",", mediaTypeIdsA)}"); scope.Complete(); } diff --git a/src/Umbraco.Core/Services/Implement/MemberService.cs b/src/Umbraco.Core/Services/Implement/MemberService.cs index 211e30d01c..3fd714f974 100644 --- a/src/Umbraco.Core/Services/Implement/MemberService.cs +++ b/src/Umbraco.Core/Services/Implement/MemberService.cs @@ -337,7 +337,7 @@ namespace Umbraco.Core.Services.Implement if (withIdentity == false) return; - Audit(AuditType.New, $"Member '{member.Name}' was created with Id {member.Id}", member.CreatorId, member.Id); + Audit(AuditType.New, member.CreatorId, member.Id, $"Member '{member.Name}' was created with Id {member.Id}"); } #endregion @@ -843,7 +843,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); } - Audit(AuditType.Save, "Save Member performed by user", 0, member.Id); + Audit(AuditType.Save, 0, member.Id); scope.Complete(); } @@ -884,7 +884,7 @@ namespace Umbraco.Core.Services.Implement saveEventArgs.CanCancel = false; scope.Events.Dispatch(Saved, this, saveEventArgs); } - Audit(AuditType.Save, "Save Member items performed by user", 0, -1); + Audit(AuditType.Save, 0, -1, "Save multiple Members"); scope.Complete(); } @@ -912,7 +912,7 @@ namespace Umbraco.Core.Services.Implement scope.WriteLock(Constants.Locks.MemberTree); DeleteLocked(scope, member, deleteEventArgs); - Audit(AuditType.Delete, "Delete Member performed by user", 0, member.Id); + Audit(AuditType.Delete, 0, member.Id); scope.Complete(); } } @@ -1089,9 +1089,9 @@ namespace Umbraco.Core.Services.Implement #region Private Methods - private void Audit(AuditType type, string message, int userId, int objectId) + private void Audit(AuditType type, int userId, int objectId, string message = null) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.Member), message)); } #endregion diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index 67e07e63b6..c0e8f80337 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -1485,7 +1485,7 @@ namespace Umbraco.Core.Services.Implement private void Audit(AuditType type, string message, int userId, int objectId) { - _auditRepository.Save(new AuditItem(objectId, message, type, userId)); + _auditRepository.Save(new AuditItem(objectId, type, userId, "Package", message)); } #endregion diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 0eba543e0d..dc5ca5e2aa 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -353,6 +353,7 @@ +