Cleaning up the log/audit trail usage, removing duplicate and unecessary entries and adding new cols
This commit is contained in:
@@ -137,6 +137,7 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
// resume at {290C18EE-B3DE-4769-84F1-1F467F3F76DA}...
|
||||
|
||||
Chain<DropTaskTables>("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}");
|
||||
Chain<AddLogTableColumns>("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
@@ -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<LogDto>("entityType");
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.Log) && !x.ColumnName.InvariantEquals("parameters")))
|
||||
AddColumn<LogDto>("parameters");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="comment"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="userId"></param>
|
||||
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; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string EntityType { get; }
|
||||
/// <inheritdoc/>
|
||||
public string Parameters { get; }
|
||||
|
||||
public AuditType AuditType { get; }
|
||||
public int UserId { get; }
|
||||
}
|
||||
|
||||
@@ -25,10 +25,20 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
[Index(IndexTypes.NonClustered, Name = "IX_umbracoLog")]
|
||||
public int NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the entity type associated with the log
|
||||
/// </summary>
|
||||
[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; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to store additional data parameters for the log
|
||||
/// </summary>
|
||||
[Column("parameters")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[Length(500)]
|
||||
public string Parameters { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<LogDto>(sql);
|
||||
return dto == null
|
||||
? null
|
||||
: new AuditItem(dto.NodeId, dto.Comment, Enum<AuditType>.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId);
|
||||
: new AuditItem(dto.NodeId, Enum<AuditType>.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IAuditItem> PerformGetAll(params int[] ids)
|
||||
@@ -69,7 +73,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
var dtos = Database.Fetch<LogDto>(sql);
|
||||
|
||||
return dtos.Select(x => new AuditItem(x.NodeId, x.Comment, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId)).ToArray();
|
||||
return dtos.Select(x => new AuditItem(x.NodeId, Enum<AuditType>.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList();
|
||||
}
|
||||
|
||||
protected override Sql<ISqlContext> 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<AuditType>.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId)).ToArray();
|
||||
dto => new AuditItem(dto.Id, Enum<AuditType>.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;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
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<IAuditItem> GetLogs(int objectId);
|
||||
IEnumerable<IAuditItem> GetUserLogs(int userId, AuditType type, DateTime? sinceDate = null);
|
||||
|
||||
@@ -27,11 +27,11 @@ namespace Umbraco.Core.Services.Implement
|
||||
_isAvailable = new Lazy<bool>(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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<IContent>(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<string> 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<IContent>(content, false, false), "Unpublished");
|
||||
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(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<IContent>(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<int>();
|
||||
|
||||
//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<IContent>(document, TreeChangeTypes.RefreshBranch).ToEventArgs());
|
||||
scope.Events.Dispatch(Published, this, new PublishEventArgs<IContent>(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<IContent>(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<IContent>(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<IContent>(copy, TreeChangeTypes.RefreshBranch).ToEventArgs());
|
||||
foreach (var x in copies)
|
||||
scope.Events.Dispatch(Copied, this, new CopyEventArgs<IContent>(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<IContent>(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<IContent>(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();
|
||||
}
|
||||
|
||||
+7
-6
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<ITemplate>(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<ITemplate>(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
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
EnsureDictionaryItemLanguageCallback(dictionaryItem);
|
||||
scope.Events.Dispatch(SavedDictionaryItem, this, new SaveEventArgs<IDictionaryItem>(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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<IMedia>(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<IMedia>(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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<IMedia>(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<IMedia>(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<IMedia>(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<IMedia>(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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -353,6 +353,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoAuditTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoConsentTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\CreateSensitiveDataUserGroup.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddLogTableColumns.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddTypedLabels.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddVariationTables1A.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddVariationTables2.cs" />
|
||||
|
||||
Reference in New Issue
Block a user