Files: moved from feature/editor-version-history

This commit is contained in:
pavelbannov 2021-12-08 15:25:39 +03:00
parent 475dd92c30
commit feb48c01a0
7 changed files with 353 additions and 222 deletions

View File

@ -97,7 +97,7 @@ namespace ASC.Files.Core.Data
services.TryAdd<ILinkDao, LinkDao>(); services.TryAdd<ILinkDao, LinkDao>();
// AddSharpBoxDaoSelectorService services.TryAdd<EditHistory>();
} }
} }
} }

View File

@ -1202,14 +1202,12 @@ namespace ASC.Files.Core.Data
.Select(r => .Select(r =>
{ {
var item = ServiceProvider.GetService<EditHistory>(); var item = ServiceProvider.GetService<EditHistory>();
var editHistoryAuthor = ServiceProvider.GetService<EditHistoryAuthor>();
editHistoryAuthor.Id = r.ModifiedBy;
item.ID = r.Id; item.ID = r.Id;
item.Version = r.Version; item.Version = r.Version;
item.VersionGroup = r.VersionGroup; item.VersionGroup = r.VersionGroup;
item.ModifiedOn = TenantUtil.DateTimeFromUtc(r.ModifiedOn); item.ModifiedOn = TenantUtil.DateTimeFromUtc(r.ModifiedOn);
item.ModifiedBy = editHistoryAuthor; item.ModifiedBy = r.ModifiedBy;
item.ChangesString = r.Changes; item.ChangesString = r.Changes;
item.Key = documentServiceHelper.GetDocKey(item.ID, item.Version, TenantUtil.DateTimeFromUtc(r.CreateOn)); item.Key = documentServiceHelper.GetDocKey(item.ID, item.Version, TenantUtil.DateTimeFromUtc(r.CreateOn));

View File

@ -1,221 +1,225 @@
/* /*
* *
* (c) Copyright Ascensio System Limited 2010-2018 * (c) Copyright Ascensio System Limited 2010-2018
* *
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
* *
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
* *
* You can contact Ascensio System SIA by email at sales@onlyoffice.com * You can contact Ascensio System SIA by email at sales@onlyoffice.com
* *
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
* *
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic * relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute. * in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization; using System.Text.Json;
using ASC.Common.Logging; using ASC.Common;
using ASC.Core; using ASC.Common.Logging;
using ASC.Core.Tenants; using ASC.Core;
using ASC.Core.Users; using ASC.Core.Tenants;
using ASC.Files.Core.Resources; using ASC.Core.Users;
using ASC.Web.Core.Users; using ASC.Files.Core.Resources;
using ASC.Web.Core.Users;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace ASC.Files.Core
namespace ASC.Files.Core {
{ [Transient]
[DebuggerDisplay("{ID} v{Version}")] [DebuggerDisplay("{ID} v{Version}")]
public class EditHistory public class EditHistory
{ {
public EditHistory( private ILog Logger { get; }
IOptionsMonitor<ILog> options, private TenantUtil TenantUtil { get; }
TenantUtil tenantUtil, private UserManager UserManager { get; }
UserManager userManager, private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
DisplayUserSettingsHelper displayUserSettingsHelper)
{ public EditHistory(
Logger = options.CurrentValue; IOptionsMonitor<ILog> options,
TenantUtil = tenantUtil; TenantUtil tenantUtil,
UserManager = userManager; UserManager userManager,
DisplayUserSettingsHelper = displayUserSettingsHelper; DisplayUserSettingsHelper displayUserSettingsHelper)
} {
Logger = options.CurrentValue;
public int ID { get; set; } TenantUtil = tenantUtil;
public string Key { get; set; } UserManager = userManager;
public int Version { get; set; } DisplayUserSettingsHelper = displayUserSettingsHelper;
public int VersionGroup { get; set; } }
[JsonPropertyName("user")] public int ID { get; set; }
public EditHistoryAuthor ModifiedBy { get; set; } public string Key { get; set; }
public int Version { get; set; }
[JsonPropertyName("changeshistory")] public int VersionGroup { get; set; }
public string ChangesString { get; set; }
public DateTime ModifiedOn { get; set; }
public List<EditHistoryChanges> Changes public Guid ModifiedBy { get; set; }
{ public string ChangesString { get; set; }
get
{ public string ServerVersion { get; set; }
var changes = new List<EditHistoryChanges>();
if (string.IsNullOrEmpty(ChangesString)) return changes; public List<EditHistoryChanges> Changes
{
try get
{ {
var jObject = JObject.Parse(ChangesString); var changes = new List<EditHistoryChanges>();
ServerVersion = jObject.Value<string>("serverVersion"); if (string.IsNullOrEmpty(ChangesString)) return changes;
try
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var jObject = JsonSerializer.Deserialize<ChangesDataList>(ChangesString, options);
ServerVersion = jObject.ServerVersion;
if (string.IsNullOrEmpty(ServerVersion)) if (string.IsNullOrEmpty(ServerVersion))
return changes; return changes;
var jChanges = jObject.Value<JArray>("changes"); changes = jObject.Changes.Select(r =>
{
changes = jChanges.Children() var result = new EditHistoryChanges()
.Select(jChange => {
{ Author = new EditHistoryAuthor(UserManager, DisplayUserSettingsHelper)
var jUser = jChange.Value<JObject>("user"); {
return new EditHistoryChanges(TenantUtil) Id = new Guid(r.User.Id ?? Guid.Empty.ToString()),
{ Name = r.User.Name,
Date = jChange.Value<string>("created"), }
Author = new EditHistoryAuthor(UserManager, DisplayUserSettingsHelper) };
{
Id = new Guid(jUser.Value<string>("id") ?? Guid.Empty.ToString()),
Name = jUser.Value<string>("name"), if (DateTime.TryParse(r.Created, out var _date))
}, {
}; _date = TenantUtil.DateTimeFromUtc(_date);
}) }
.ToList(); result.Date = _date;
return changes;
} return result;
catch (Exception ex) })
{ .ToList();
Logger.Error("DeSerialize old scheme exception", ex);
} return changes;
}
return changes; catch (Exception ex)
} {
set { throw new NotImplementedException(); } Logger.Error("DeSerialize old scheme exception", ex);
} }
public DateTime ModifiedOn; return changes;
}
[JsonPropertyName("created")] set { throw new NotImplementedException(); }
public string ModifiedOnString }
{ }
get { return ModifiedOn.Equals(default) ? null : ModifiedOn.ToString("g"); }
set { throw new NotImplementedException(); } class ChangesDataList
} {
public string ServerVersion { get; set; }
public ILog Logger { get; } public ChangesData[] Changes { get; set; }
private TenantUtil TenantUtil { get; } }
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } class ChangesData
{
public string ServerVersion; public string Created { get; set; }
} public ChangesUserData User { get; set; }
}
[DebuggerDisplay("{Id} {Name}")]
public class EditHistoryAuthor class ChangesUserData
{ {
public EditHistoryAuthor( public string Id { get; set; }
UserManager userManager, public string Name { get; set; }
DisplayUserSettingsHelper displayUserSettingsHelper) }
{
UserManager = userManager; [Transient]
DisplayUserSettingsHelper = displayUserSettingsHelper; [DebuggerDisplay("{Id} {Name}")]
} public class EditHistoryAuthor
{
public Guid Id { get; set; } public EditHistoryAuthor(
UserManager userManager,
private string _name; DisplayUserSettingsHelper displayUserSettingsHelper)
{
public string Name UserManager = userManager;
{ DisplayUserSettingsHelper = displayUserSettingsHelper;
get }
{
UserInfo user; public Guid Id { get; set; }
return
Id.Equals(Guid.Empty) private string _name;
|| Id.Equals(ASC.Core.Configuration.Constants.Guest.ID)
|| (user = UserManager.GetUsers(Id)).Equals(Constants.LostUser) public string Name
? string.IsNullOrEmpty(_name) {
? FilesCommonResource.Guest get
: _name {
: user.DisplayUserName(false, DisplayUserSettingsHelper); UserInfo user;
} return
set { _name = value; } Id.Equals(Guid.Empty)
} || Id.Equals(ASC.Core.Configuration.Constants.Guest.ID)
|| (user = UserManager.GetUsers(Id)).Equals(Constants.LostUser)
private UserManager UserManager { get; } ? string.IsNullOrEmpty(_name)
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } ? FilesCommonResource.Guest
} : _name
: user.DisplayUserName(false, DisplayUserSettingsHelper);
[DebuggerDisplay("{Author.Name}")] }
public class EditHistoryChanges set { _name = value; }
{ }
public EditHistoryChanges(TenantUtil tenantUtil)
{ private UserManager UserManager { get; }
TenantUtil = tenantUtil; private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
} }
[JsonPropertyName("user")] [DebuggerDisplay("{Author.Name}")]
public EditHistoryAuthor Author { get; set; } public class EditHistoryChanges
{
private DateTime _date; public EditHistoryAuthor Author { get; set; }
[JsonPropertyName("created")] public DateTime Date { get; set; }
public string Date
{
get { return _date.Equals(default) ? null : _date.ToString("g"); } }
set
{ [DebuggerDisplay("{Version}")]
if (DateTime.TryParse(value, out _date)) public class EditHistoryData
{ {
_date = TenantUtil.DateTimeFromUtc(_date); public string ChangesUrl { get; set; }
}
} public string Key { get; set; }
}
public EditHistoryUrl Previous { get; set; }
private TenantUtil TenantUtil { get; }
} public string Token { get; set; }
[DebuggerDisplay("{Version}")] public string Url { get; set; }
public class EditHistoryData
{ public int Version { get; set; }
public string ChangesUrl { get; set; }
public string FileType { get; set; }
public string Key { get; set; } }
public EditHistoryUrl Previous { get; set; } [DebuggerDisplay("{Key} - {Url}")]
public class EditHistoryUrl
public string Token { get; set; } {
public string Key { get; set; }
public string Url { get; set; }
public string Url { get; set; }
public int Version { get; set; }
} public string FileType { get; set; }
}
[DebuggerDisplay("{Key} - {Url}")]
public class EditHistoryUrl
{
public string Key { get; set; }
public string Url { get; set; }
}
} }

View File

@ -1071,12 +1071,15 @@ namespace ASC.Web.Files.Services.WCFService
Key = DocumentServiceHelper.GetDocKey(file), Key = DocumentServiceHelper.GetDocKey(file),
Url = DocumentServiceConnector.ReplaceCommunityAdress(PathProvider.GetFileStreamUrl(file, doc)), Url = DocumentServiceConnector.ReplaceCommunityAdress(PathProvider.GetFileStreamUrl(file, doc)),
Version = version, Version = version,
FileType = GetFileExtensionWithoutDot(FileUtility.GetFileExtension(file.Title))
}; };
if (fileDao.ContainChanges(file.ID, file.Version)) if (fileDao.ContainChanges(file.ID, file.Version))
{ {
string previouseKey; string previouseKey;
string sourceFileUrl; string sourceFileUrl;
string previousFileExt;
if (file.Version > 1) if (file.Version > 1)
{ {
var previousFileStable = fileDao.GetFileStable(file.ID, file.Version - 1); var previousFileStable = fileDao.GetFileStable(file.ID, file.Version - 1);
@ -1085,6 +1088,7 @@ namespace ASC.Web.Files.Services.WCFService
sourceFileUrl = PathProvider.GetFileStreamUrl(previousFileStable, doc); sourceFileUrl = PathProvider.GetFileStreamUrl(previousFileStable, doc);
previouseKey = DocumentServiceHelper.GetDocKey(previousFileStable); previouseKey = DocumentServiceHelper.GetDocKey(previousFileStable);
previousFileExt = FileUtility.GetFileExtension(previousFileStable.Title);
} }
else else
{ {
@ -1105,12 +1109,14 @@ namespace ASC.Web.Files.Services.WCFService
sourceFileUrl = BaseCommonLinkUtility.GetFullAbsolutePath(sourceFileUrl); sourceFileUrl = BaseCommonLinkUtility.GetFullAbsolutePath(sourceFileUrl);
previouseKey = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); previouseKey = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString());
previousFileExt = fileExt;
} }
result.Previous = new EditHistoryUrl result.Previous = new EditHistoryUrl
{ {
Key = previouseKey, Key = previouseKey,
Url = DocumentServiceConnector.ReplaceCommunityAdress(sourceFileUrl), Url = DocumentServiceConnector.ReplaceCommunityAdress(sourceFileUrl),
FileType = GetFileExtensionWithoutDot(previousFileExt)
}; };
result.ChangesUrl = PathProvider.GetFileChangesUrl(file, doc); result.ChangesUrl = PathProvider.GetFileChangesUrl(file, doc);
} }
@ -1118,6 +1124,11 @@ namespace ASC.Web.Files.Services.WCFService
result.Token = DocumentServiceHelper.GetSignature(result); result.Token = DocumentServiceHelper.GetSignature(result);
return result; return result;
string GetFileExtensionWithoutDot(string ext)
{
return ext.Substring(ext.IndexOf('.') + 1);
}
} }
public List<EditHistory> RestoreVersion(T fileId, int version, string url = null, string doc = null) public List<EditHistory> RestoreVersion(T fileId, int version, string url = null, string doc = null)

View File

@ -0,0 +1,49 @@

using System.Collections.Generic;
using System.Linq;
using ASC.Api.Core;
using ASC.Core;
using ASC.Web.Core.Users;
namespace ASC.Files.Core.Model
{
public class EditHistoryWrapper
{
public int ID { get; set; }
public string Key { get; set; }
public int Version { get; set; }
public int VersionGroup { get; set; }
public EditHistoryAuthor User { get; set; }
public ApiDateTime Created { get; set; }
public string ChangesHistory { get; set; }
public List<EditHistoryChangesWrapper> Changes { get; set; }
public string ServerVersion { get; set; }
public EditHistoryWrapper(EditHistory editHistory, ApiDateTimeHelper apiDateTimeHelper, UserManager userManager, DisplayUserSettingsHelper displayUserSettingsHelper)
{
ID = editHistory.ID;
Key = editHistory.Key;
Version = editHistory.Version;
VersionGroup = editHistory.VersionGroup;
Changes = editHistory.Changes.Select(r => new EditHistoryChangesWrapper(r, apiDateTimeHelper)).ToList();
ChangesHistory = editHistory.ChangesString;
Created = apiDateTimeHelper.Get(editHistory.ModifiedOn);
User = new EditHistoryAuthor(userManager, displayUserSettingsHelper) { Id = editHistory.ModifiedBy };
ServerVersion = editHistory.ServerVersion;
}
}
public class EditHistoryChangesWrapper
{
public EditHistoryAuthor User { get; set; }
public ApiDateTime Created { get; set; }
public EditHistoryChangesWrapper(EditHistoryChanges historyChanges, ApiDateTimeHelper apiDateTimeHelper)
{
User = historyChanges.Author;
Created = apiDateTimeHelper.Get(historyChanges.Date);
}
}
}

View File

@ -1517,6 +1517,48 @@ namespace ASC.Api.Documents
return FilesControllerHelperInt.LockFile(fileId, model.LockFile); return FilesControllerHelperInt.LockFile(fileId, model.LockFile);
} }
[AllowAnonymous]
[Read("file/{fileId}/edit/history")]
public List<EditHistoryWrapper> GetEditHistory(string fileId, string doc = null)
{
return FilesControllerHelperString.GetEditHistory(fileId, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/edit/history")]
public List<EditHistoryWrapper> GetEditHistory(int fileId, string doc = null)
{
return FilesControllerHelperInt.GetEditHistory(fileId, doc);
}
[AllowAnonymous]
[Read("file/{fileId}/edit/diff")]
public EditHistoryData GetEditDiffUrl(string fileId, int version = 0, string doc = null)
{
return FilesControllerHelperString.GetEditDiffUrl(fileId, version, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/edit/diff")]
public EditHistoryData GetEditDiffUrl(int fileId, int version = 0, string doc = null)
{
return FilesControllerHelperInt.GetEditDiffUrl(fileId, version, doc);
}
[AllowAnonymous]
[Read("file/{fileId}/restoreversion")]
public List<EditHistoryWrapper> RestoreVersion(string fileId, int version = 0, string url = null, string doc = null)
{
return FilesControllerHelperString.RestoreVersion(fileId, version, url, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/restoreversion")]
public List<EditHistoryWrapper> RestoreVersion(int fileId, int version = 0, string url = null, string doc = null)
{
return FilesControllerHelperInt.RestoreVersion(fileId, version, url, doc);
}
[Update("file/{fileId}/comment")] [Update("file/{fileId}/comment")]
public object UpdateCommentFromBody(string fileId, [FromBody] UpdateCommentModel model) public object UpdateCommentFromBody(string fileId, [FromBody] UpdateCommentModel model)
{ {

View File

@ -21,6 +21,7 @@ using ASC.Files.Core;
using ASC.Files.Core.Model; using ASC.Files.Core.Model;
using ASC.Files.Model; using ASC.Files.Model;
using ASC.Web.Core.Files; using ASC.Web.Core.Files;
using ASC.Web.Core.Users;
using ASC.Web.Files.Classes; using ASC.Web.Files.Classes;
using ASC.Web.Files.Core.Entries; using ASC.Web.Files.Core.Entries;
using ASC.Web.Files.Services.DocumentService; using ASC.Web.Files.Services.DocumentService;
@ -66,6 +67,9 @@ namespace ASC.Files.Helpers
private EncryptionKeyPairHelper EncryptionKeyPairHelper { get; } private EncryptionKeyPairHelper EncryptionKeyPairHelper { get; }
private IHttpContextAccessor HttpContextAccessor { get; } private IHttpContextAccessor HttpContextAccessor { get; }
private FileConverter FileConverter { get; } private FileConverter FileConverter { get; }
private ApiDateTimeHelper ApiDateTimeHelper { get; }
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private ILog Logger { get; set; } private ILog Logger { get; set; }
/// <summary> /// <summary>
@ -94,7 +98,10 @@ namespace ASC.Files.Helpers
SettingsManager settingsManager, SettingsManager settingsManager,
EncryptionKeyPairHelper encryptionKeyPairHelper, EncryptionKeyPairHelper encryptionKeyPairHelper,
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor,
FileConverter fileConverter) FileConverter fileConverter,
ApiDateTimeHelper apiDateTimeHelper,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{ {
ApiContext = context; ApiContext = context;
FileStorageService = fileStorageService; FileStorageService = fileStorageService;
@ -115,6 +122,9 @@ namespace ASC.Files.Helpers
DocumentServiceTracker = documentServiceTracker; DocumentServiceTracker = documentServiceTracker;
SettingsManager = settingsManager; SettingsManager = settingsManager;
EncryptionKeyPairHelper = encryptionKeyPairHelper; EncryptionKeyPairHelper = encryptionKeyPairHelper;
ApiDateTimeHelper = apiDateTimeHelper;
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
HttpContextAccessor = httpContextAccessor; HttpContextAccessor = httpContextAccessor;
FileConverter = fileConverter; FileConverter = fileConverter;
Logger = optionMonitor.Get("ASC.Files"); Logger = optionMonitor.Get("ASC.Files");
@ -571,6 +581,23 @@ namespace ASC.Files.Helpers
return FileStorageService.GetPresignedUri(fileId); return FileStorageService.GetPresignedUri(fileId);
} }
public List<EditHistoryWrapper> GetEditHistory(T fileId, string doc = null)
{
var result = FileStorageService.GetEditHistory(fileId, doc);
return result.Select(r => new EditHistoryWrapper(r, ApiDateTimeHelper, UserManager, DisplayUserSettingsHelper)).ToList();
}
public EditHistoryData GetEditDiffUrl(T fileId, int version = 0, string doc = null)
{
return FileStorageService.GetEditDiffUrl(fileId, version, doc);
}
public List<EditHistoryWrapper> RestoreVersion(T fileId, int version = 0, string url = null, string doc = null)
{
var result = FileStorageService.RestoreVersion(fileId, version, url, doc);
return result.Select(r => new EditHistoryWrapper(r, ApiDateTimeHelper, UserManager, DisplayUserSettingsHelper)).ToList();
}
public string UpdateComment(T fileId, int version, string comment) public string UpdateComment(T fileId, int version, string comment)
{ {
return FileStorageService.UpdateComment(fileId, version, comment); return FileStorageService.UpdateComment(fileId, version, comment);