DocSpace-client/products/ASC.Files/Server/Utils/EntryManager.cs

1419 lines
63 KiB
C#
Raw Normal View History

2020-01-27 11:15:18 +00:00
/*
*
* (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
* 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
* 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
* 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
*
* 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.
*
* 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
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* 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.
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security;
using System.Text;
using System.Threading;
2020-02-05 08:30:04 +00:00
2020-02-17 08:58:14 +00:00
using ASC.Common;
2020-01-27 11:15:18 +00:00
using ASC.Common.Caching;
2020-02-05 08:30:04 +00:00
using ASC.Common.Logging;
2020-01-27 11:15:18 +00:00
using ASC.Core;
using ASC.Core.Users;
using ASC.Files.Core;
2020-02-13 12:19:25 +00:00
using ASC.Files.Core.Data;
2020-02-05 08:30:04 +00:00
using ASC.Files.Core.Security;
2020-02-18 08:39:28 +00:00
using ASC.Files.Resources;
2020-01-27 11:15:18 +00:00
using ASC.Web.Core.Files;
using ASC.Web.Files.Api;
using ASC.Web.Files.Classes;
using ASC.Web.Files.Core;
using ASC.Web.Files.Helpers;
using ASC.Web.Files.Services.DocumentService;
using ASC.Web.Files.ThirdPartyApp;
2020-02-05 08:30:04 +00:00
2020-02-10 16:04:54 +00:00
using Microsoft.Extensions.DependencyInjection;
2020-02-05 08:30:04 +00:00
using Microsoft.Extensions.Options;
2020-01-27 11:15:18 +00:00
using Newtonsoft.Json.Linq;
2020-02-05 08:30:04 +00:00
2020-01-27 11:15:18 +00:00
using File = ASC.Files.Core.File;
using FileShare = ASC.Files.Core.Security.FileShare;
namespace ASC.Web.Files.Utils
{
2020-02-13 12:19:25 +00:00
public class LockerManager
{
public AuthContext AuthContext { get; }
public IDaoFactory DaoFactory { get; }
public LockerManager(AuthContext authContext, IDaoFactory daoFactory)
{
AuthContext = authContext;
DaoFactory = daoFactory;
}
public bool FileLockedForMe(object fileId, Guid userId = default)
{
var app = ThirdPartySelector.GetAppByFileId(fileId.ToString());
if (app != null)
{
return false;
}
userId = userId == default ? AuthContext.CurrentAccount.ID : userId;
var tagDao = DaoFactory.TagDao;
var lockedBy = FileLockedBy(fileId, tagDao);
return lockedBy != Guid.Empty && lockedBy != userId;
}
public Guid FileLockedBy(object fileId, ITagDao tagDao)
{
var tagLock = tagDao.GetTags(fileId, FileEntryType.File, TagType.Locked).FirstOrDefault();
return tagLock != null ? tagLock.Owner : Guid.Empty;
}
}
2020-02-14 10:45:46 +00:00
public class BreadCrumbsManager
{
public IDaoFactory DaoFactory { get; }
public FileSecurity FileSecurity { get; }
public GlobalFolderHelper GlobalFolderHelper { get; }
public AuthContext AuthContext { get; }
public BreadCrumbsManager(
IDaoFactory daoFactory,
FileSecurity fileSecurity,
GlobalFolderHelper globalFolderHelper,
AuthContext authContext)
{
DaoFactory = daoFactory;
FileSecurity = fileSecurity;
GlobalFolderHelper = globalFolderHelper;
AuthContext = authContext;
}
public List<Folder> GetBreadCrumbs(object folderId)
{
var folderDao = DaoFactory.FolderDao;
return GetBreadCrumbs(folderId, folderDao);
}
public List<Folder> GetBreadCrumbs(object folderId, IFolderDao folderDao)
{
if (folderId == null) return new List<Folder>();
var breadCrumbs = FileSecurity.FilterRead(folderDao.GetParentFolders(folderId)).ToList();
var firstVisible = breadCrumbs.ElementAtOrDefault(0);
object rootId = null;
if (firstVisible == null)
{
rootId = GlobalFolderHelper.FolderShare;
}
else
{
switch (firstVisible.FolderType)
{
case FolderType.DEFAULT:
if (!firstVisible.ProviderEntry)
{
rootId = GlobalFolderHelper.FolderShare;
}
else
{
switch (firstVisible.RootFolderType)
{
case FolderType.USER:
rootId = AuthContext.CurrentAccount.ID == firstVisible.RootFolderCreator
? GlobalFolderHelper.FolderMy
: GlobalFolderHelper.FolderShare;
break;
case FolderType.COMMON:
rootId = GlobalFolderHelper.FolderCommon;
break;
}
}
break;
case FolderType.BUNCH:
rootId = GlobalFolderHelper.FolderProjects;
break;
}
}
if (rootId != null)
{
breadCrumbs.Insert(0, folderDao.GetFolder(rootId));
}
return breadCrumbs;
}
}
2020-01-27 11:15:18 +00:00
public class EntryManager
{
private const string UPDATE_LIST = "filesUpdateList";
2020-02-11 09:39:32 +00:00
private readonly ICache cache;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
public IDaoFactory DaoFactory { get; }
public FileSecurity FileSecurity { get; }
public GlobalFolderHelper GlobalFolderHelper { get; }
public PathProvider PathProvider { get; }
public AuthContext AuthContext { get; }
public FilesIntegration FilesIntegration { get; }
public FileMarker FileMarker { get; }
public FileUtility FileUtility { get; }
public Global Global { get; }
public GlobalStore GlobalStore { get; }
public CoreBaseSettings CoreBaseSettings { get; }
public FilesSettingsHelper FilesSettingsHelper { get; }
public UserManager UserManager { get; }
2020-02-06 11:55:11 +00:00
public FileShareLink FileShareLink { get; }
2020-02-06 13:06:36 +00:00
public DocumentServiceHelper DocumentServiceHelper { get; }
public ThirdpartyConfiguration ThirdpartyConfiguration { get; }
2020-02-07 10:29:16 +00:00
public DocumentServiceConnector DocumentServiceConnector { get; }
2020-02-13 12:19:25 +00:00
public LockerManager LockerManager { get; }
2020-02-14 10:45:46 +00:00
public BreadCrumbsManager BreadCrumbsManager { get; }
2020-02-10 16:04:54 +00:00
public IServiceProvider ServiceProvider { get; }
2020-02-05 08:30:04 +00:00
public ILog Logger { get; }
public EntryManager(
IDaoFactory daoFactory,
FileSecurity fileSecurity,
GlobalFolderHelper globalFolderHelper,
PathProvider pathProvider,
AuthContext authContext,
FilesIntegration filesIntegration,
FileMarker fileMarker,
FileUtility fileUtility,
Global global,
GlobalStore globalStore,
CoreBaseSettings coreBaseSettings,
FilesSettingsHelper filesSettingsHelper,
UserManager userManager,
2020-02-06 11:55:11 +00:00
IOptionsMonitor<ILog> optionsMonitor,
2020-02-06 13:06:36 +00:00
FileShareLink fileShareLink,
DocumentServiceHelper documentServiceHelper,
2020-02-07 10:29:16 +00:00
ThirdpartyConfiguration thirdpartyConfiguration,
2020-02-10 16:04:54 +00:00
DocumentServiceConnector documentServiceConnector,
2020-02-13 12:19:25 +00:00
LockerManager lockerManager,
2020-02-14 10:45:46 +00:00
BreadCrumbsManager breadCrumbsManager,
2020-02-10 16:04:54 +00:00
IServiceProvider serviceProvider)
2020-02-05 08:30:04 +00:00
{
DaoFactory = daoFactory;
FileSecurity = fileSecurity;
GlobalFolderHelper = globalFolderHelper;
PathProvider = pathProvider;
AuthContext = authContext;
FilesIntegration = filesIntegration;
FileMarker = fileMarker;
FileUtility = fileUtility;
Global = global;
GlobalStore = globalStore;
CoreBaseSettings = coreBaseSettings;
FilesSettingsHelper = filesSettingsHelper;
UserManager = userManager;
2020-02-06 11:55:11 +00:00
FileShareLink = fileShareLink;
2020-02-06 13:06:36 +00:00
DocumentServiceHelper = documentServiceHelper;
ThirdpartyConfiguration = thirdpartyConfiguration;
2020-02-07 10:29:16 +00:00
DocumentServiceConnector = documentServiceConnector;
2020-02-13 12:19:25 +00:00
LockerManager = lockerManager;
2020-02-14 10:45:46 +00:00
BreadCrumbsManager = breadCrumbsManager;
2020-02-10 16:04:54 +00:00
ServiceProvider = serviceProvider;
2020-02-05 08:30:04 +00:00
Logger = optionsMonitor.CurrentValue;
2020-02-11 09:39:32 +00:00
cache = AscCache.Memory;
2020-02-05 08:30:04 +00:00
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
public IEnumerable<FileEntry> GetEntries(Folder parent, int from, int count, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy, out int total)
2020-01-27 11:15:18 +00:00
{
total = 0;
if (parent == null) throw new ArgumentNullException("parent", FilesCommonResource.ErrorMassage_FolderNotFound);
2020-02-05 08:30:04 +00:00
var fileSecurity = FileSecurity;
2020-01-27 11:15:18 +00:00
var entries = Enumerable.Empty<FileEntry>();
2020-02-05 08:30:04 +00:00
searchInContent = searchInContent && filter != FilterType.ByExtension && !Equals(parent.ID, GlobalFolderHelper.FolderTrash);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (parent.FolderType == FolderType.Projects && parent.ID.Equals(GlobalFolderHelper.FolderProjects))
2020-01-27 11:15:18 +00:00
{
2020-02-11 15:15:39 +00:00
//TODO
//var apiServer = new ASC.Api.ApiServer();
//var apiUrl = string.Format("{0}project/maxlastmodified.json", SetupInfo.WebApiBaseUrl);
2020-01-27 11:15:18 +00:00
2020-02-11 15:15:39 +00:00
string responseBody = null;// apiServer.GetApiResponse(apiUrl, "GET");
2020-01-27 11:15:18 +00:00
if (responseBody != null)
{
var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(responseBody)));
2020-01-27 14:58:33 +00:00
var projectLastModified = responseApi["response"].Value<string>();
2020-01-27 11:15:18 +00:00
const string projectLastModifiedCacheKey = "documents/projectFolders/projectLastModified";
2020-02-05 08:30:04 +00:00
var projectListCacheKey = string.Format("documents/projectFolders/{0}", AuthContext.CurrentAccount.ID);
2020-02-11 09:39:32 +00:00
Dictionary<object, KeyValuePair<int, string>> folderIDProjectTitle = null;
2020-01-27 11:15:18 +00:00
if (folderIDProjectTitle == null)
{
2020-02-11 15:15:39 +00:00
//apiUrl = string.Format("{0}project/filter.json?sortBy=title&sortOrder=ascending&status=open&fields=id,title,security,projectFolder", SetupInfo.WebApiBaseUrl);
2020-01-27 11:15:18 +00:00
2020-02-11 15:15:39 +00:00
responseApi = JObject.Parse(""); //Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))));
2020-01-27 11:15:18 +00:00
var responseData = responseApi["response"];
if (!(responseData is JArray)) return entries.ToList();
folderIDProjectTitle = new Dictionary<object, KeyValuePair<int, string>>();
foreach (JObject projectInfo in responseData.Children())
{
var projectID = projectInfo["id"].Value<int>();
2020-01-27 14:58:33 +00:00
var projectTitle = Global.ReplaceInvalidCharsAndTruncate(projectInfo["title"].Value<string>());
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (projectInfo.TryGetValue("security", out var projectSecurityJToken))
2020-01-27 11:15:18 +00:00
{
var projectSecurity = projectInfo["security"].Value<JObject>();
2020-02-05 08:30:04 +00:00
if (projectSecurity.TryGetValue("canReadFiles", out var projectCanFileReadJToken))
2020-01-27 11:15:18 +00:00
{
if (!projectSecurity["canReadFiles"].Value<bool>())
{
continue;
}
}
}
int projectFolderID;
2020-02-05 08:30:04 +00:00
if (projectInfo.TryGetValue("projectFolder", out var projectFolderIDjToken))
2020-01-27 11:15:18 +00:00
projectFolderID = projectFolderIDjToken.Value<int>();
else
projectFolderID = (int)FilesIntegration.RegisterBunch("projects", "project", projectID.ToString());
if (!folderIDProjectTitle.ContainsKey(projectFolderID))
folderIDProjectTitle.Add(projectFolderID, new KeyValuePair<int, string>(projectID, projectTitle));
2020-02-11 09:39:32 +00:00
AscCache.Memory.Remove("documents/folders/" + projectFolderID);
AscCache.Memory.Insert("documents/folders/" + projectFolderID, projectTitle, TimeSpan.FromMinutes(30));
2020-01-27 11:15:18 +00:00
}
}
var rootKeys = folderIDProjectTitle.Keys.ToArray();
if (filter == FilterType.None || filter == FilterType.FoldersOnly)
{
2020-02-05 08:30:04 +00:00
var folders = DaoFactory.FolderDao.GetFolders(rootKeys, filter, subjectGroup, subjectId, searchText, withSubfolders, false);
2020-01-27 11:15:18 +00:00
var emptyFilter = string.IsNullOrEmpty(searchText) && filter == FilterType.None && subjectId == Guid.Empty;
if (!emptyFilter)
{
var projectFolderIds =
folderIDProjectTitle
.Where(projectFolder => string.IsNullOrEmpty(searchText)
|| (projectFolder.Value.Value ?? "").ToLower().Trim().Contains(searchText.ToLower().Trim()))
.Select(projectFolder => projectFolder.Key);
folders.RemoveAll(folder => rootKeys.Contains(folder.ID));
2020-02-05 08:30:04 +00:00
var projectFolders = DaoFactory.FolderDao.GetFolders(projectFolderIds.ToArray(), filter, subjectGroup, subjectId, null, false, false);
2020-01-27 11:15:18 +00:00
folders.AddRange(projectFolders);
}
folders.ForEach(x =>
{
x.Title = folderIDProjectTitle.ContainsKey(x.ID) ? folderIDProjectTitle[x.ID].Value : x.Title;
x.FolderUrl = folderIDProjectTitle.ContainsKey(x.ID) ? PathProvider.GetFolderUrl(x, folderIDProjectTitle[x.ID].Key) : string.Empty;
});
if (withSubfolders)
{
folders = fileSecurity.FilterRead(folders).ToList();
}
entries = entries.Concat(folders);
}
if (filter != FilterType.FoldersOnly && withSubfolders)
{
2020-02-05 08:30:04 +00:00
var files = DaoFactory.FileDao.GetFiles(rootKeys, filter, subjectGroup, subjectId, searchText, searchInContent).ToList();
2020-01-27 11:15:18 +00:00
files = fileSecurity.FilterRead(files).ToList();
entries = entries.Concat(files);
}
}
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder)f).TotalFiles : 1));
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder)f).TotalSubFolders + 1 : 0));
}
else if (parent.FolderType == FolderType.SHARE)
{
//share
var shared = (IEnumerable<FileEntry>)fileSecurity.GetSharesForMe(filter, subjectGroup, subjectId, searchText, searchInContent, withSubfolders);
entries = entries.Concat(shared);
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder)f).TotalFiles : 1));
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder)f).TotalSubFolders + 1 : 0));
}
else
{
if (parent.FolderType == FolderType.TRASH)
withSubfolders = false;
2020-02-05 08:30:04 +00:00
var folders = DaoFactory.FolderDao.GetFolders(parent.ID, orderBy, filter, subjectGroup, subjectId, searchText, withSubfolders).Cast<FileEntry>();
2020-01-27 11:15:18 +00:00
folders = fileSecurity.FilterRead(folders);
entries = entries.Concat(folders);
2020-02-05 08:30:04 +00:00
var files = DaoFactory.FileDao.GetFiles(parent.ID, orderBy, filter, subjectGroup, subjectId, searchText, searchInContent, withSubfolders).Cast<FileEntry>();
2020-01-27 11:15:18 +00:00
files = fileSecurity.FilterRead(files);
entries = entries.Concat(files);
if (filter == FilterType.None || filter == FilterType.FoldersOnly)
{
var folderList = GetThirpartyFolders(parent, searchText);
var thirdPartyFolder = FilterEntries(folderList, filter, subjectGroup, subjectId, searchText, searchInContent);
entries = entries.Concat(thirdPartyFolder);
}
}
if (orderBy.SortedBy != SortedByType.New)
{
entries = SortEntries(entries, orderBy);
total = entries.Count();
if (0 < from) entries = entries.Skip(from);
if (0 < count) entries = entries.Take(count);
}
2020-02-05 08:30:04 +00:00
entries = FileMarker.SetTagsNew(parent, entries);
2020-01-27 11:15:18 +00:00
//sorting after marking
if (orderBy.SortedBy == SortedByType.New)
{
entries = SortEntries(entries, orderBy);
total = entries.Count();
if (0 < from) entries = entries.Skip(from);
if (0 < count) entries = entries.Take(count);
}
SetFileStatus(entries.Where(r => r != null && r.ID != null && r.FileEntryType == FileEntryType.File).Select(r => r as File).ToList());
return entries;
}
2020-02-05 08:30:04 +00:00
public IEnumerable<Folder> GetThirpartyFolders(Folder parent, string searchText = null)
2020-01-27 11:15:18 +00:00
{
var folderList = new List<Folder>();
2020-02-05 08:30:04 +00:00
if ((parent.ID.Equals(GlobalFolderHelper.FolderMy) || parent.ID.Equals(GlobalFolderHelper.FolderCommon))
2020-01-27 11:15:18 +00:00
&& ThirdpartyConfiguration.SupportInclusion
&& (Global.IsAdministrator
2020-02-05 08:30:04 +00:00
|| CoreBaseSettings.Personal
|| FilesSettingsHelper.EnableThirdParty))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var providerDao = DaoFactory.ProviderDao;
if (providerDao == null) return folderList;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var fileSecurity = FileSecurity;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var providers = providerDao.GetProvidersInfo(parent.RootFolderType, searchText);
folderList = providers
.Select(providerInfo => GetFakeThirdpartyFolder(providerInfo, parent.ID))
.Where(fileSecurity.CanRead).ToList();
2020-01-27 11:15:18 +00:00
if (folderList.Any())
2020-02-05 08:30:04 +00:00
{
var securityDao = DaoFactory.SecurityDao;
securityDao.GetPureShareRecords(folderList.Cast<FileEntry>().ToArray())
//.Where(x => x.Owner == SecurityContext.CurrentAccount.ID)
.Select(x => x.EntryId).Distinct().ToList()
.ForEach(id =>
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
folderList.First(y => y.ID.Equals(id)).Shared = true;
});
}
2020-01-27 11:15:18 +00:00
}
return folderList;
}
2020-02-05 08:30:04 +00:00
public IEnumerable<FileEntry> FilterEntries(IEnumerable<FileEntry> entries, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
2020-01-27 11:15:18 +00:00
{
if (entries == null || !entries.Any()) return entries;
if (subjectId != Guid.Empty)
{
entries = entries.Where(f =>
subjectGroup
2020-02-05 08:30:04 +00:00
? UserManager.GetUsersByGroup(subjectId).Any(s => s.ID == f.CreateBy)
2020-01-27 11:15:18 +00:00
: f.CreateBy == subjectId
)
.ToList();
}
Func<FileEntry, bool> where = null;
switch (filter)
{
case FilterType.SpreadsheetsOnly:
case FilterType.PresentationsOnly:
case FilterType.ImagesOnly:
case FilterType.DocumentsOnly:
case FilterType.ArchiveOnly:
case FilterType.FilesOnly:
case FilterType.MediaOnly:
where = f => f.FileEntryType == FileEntryType.File && (((File)f).FilterType == filter || filter == FilterType.FilesOnly);
break;
case FilterType.FoldersOnly:
where = f => f.FileEntryType == FileEntryType.Folder;
break;
case FilterType.ByExtension:
var filterExt = (searchText ?? string.Empty).ToLower().Trim();
where = f => !string.IsNullOrEmpty(filterExt) && f.FileEntryType == FileEntryType.File && FileUtility.GetFileExtension(f.Title).Contains(filterExt);
break;
}
if (where != null)
{
entries = entries.Where(where).ToList();
}
if ((!searchInContent || filter == FilterType.ByExtension) && !string.IsNullOrEmpty(searchText = (searchText ?? string.Empty).ToLower().Trim()))
{
entries = entries.Where(f => f.Title.ToLower().Contains(searchText)).ToList();
}
return entries;
}
2020-02-05 08:30:04 +00:00
public IEnumerable<FileEntry> SortEntries(IEnumerable<FileEntry> entries, OrderBy orderBy)
2020-01-27 11:15:18 +00:00
{
if (entries == null || !entries.Any()) return entries;
Comparison<FileEntry> sorter;
if (orderBy == null)
{
2020-02-05 08:30:04 +00:00
orderBy = FilesSettingsHelper.DefaultOrder;
2020-01-27 11:15:18 +00:00
}
var c = orderBy.IsAsc ? 1 : -1;
switch (orderBy.SortedBy)
{
case SortedByType.Type:
sorter = (x, y) =>
{
var cmp = 0;
if (x.FileEntryType == FileEntryType.File && y.FileEntryType == FileEntryType.File)
cmp = c * (FileUtility.GetFileExtension((x.Title)).CompareTo(FileUtility.GetFileExtension(y.Title)));
return cmp == 0 ? x.Title.EnumerableComparer(y.Title) : cmp;
};
break;
case SortedByType.Author:
sorter = (x, y) =>
{
var cmp = c * string.Compare(x.ModifiedByString, y.ModifiedByString);
return cmp == 0 ? x.Title.EnumerableComparer(y.Title) : cmp;
};
break;
case SortedByType.Size:
sorter = (x, y) =>
{
var cmp = 0;
if (x.FileEntryType == FileEntryType.File && y.FileEntryType == FileEntryType.File)
cmp = c * ((File)x).ContentLength.CompareTo(((File)y).ContentLength);
return cmp == 0 ? x.Title.EnumerableComparer(y.Title) : cmp;
};
break;
case SortedByType.AZ:
sorter = (x, y) => c * x.Title.EnumerableComparer(y.Title);
break;
case SortedByType.DateAndTime:
sorter = (x, y) =>
{
var cmp = c * DateTime.Compare(x.ModifiedOn, y.ModifiedOn);
return cmp == 0 ? x.Title.EnumerableComparer(y.Title) : cmp;
};
break;
case SortedByType.DateAndTimeCreation:
sorter = (x, y) =>
{
var cmp = c * DateTime.Compare(x.CreateOn, y.CreateOn);
return cmp == 0 ? x.Title.EnumerableComparer(y.Title) : cmp;
};
break;
case SortedByType.New:
sorter = (x, y) =>
{
var isNewSortResult = x.IsNew.CompareTo(y.IsNew);
return c * (isNewSortResult == 0 ? DateTime.Compare(x.ModifiedOn, y.ModifiedOn) : isNewSortResult);
};
break;
default:
sorter = (x, y) => c * x.Title.EnumerableComparer(y.Title);
break;
}
if (orderBy.SortedBy != SortedByType.New)
{
// folders on top
var folders = entries.Where(r => r.FileEntryType == FileEntryType.Folder).ToList();
var files = entries.Where(r => r.FileEntryType == FileEntryType.File).ToList();
folders.Sort(sorter);
files.Sort(sorter);
return folders.Concat(files);
}
var result = entries.ToList();
result.Sort(sorter);
return result;
}
2020-02-11 11:51:45 +00:00
public Folder GetFakeThirdpartyFolder(IProviderInfo providerInfo, object parentFolderId = null)
2020-01-27 11:15:18 +00:00
{
//Fake folder. Don't send request to third party
2020-02-11 11:51:45 +00:00
var folder = ServiceProvider.GetService<Folder>();
folder.ParentFolderID = parentFolderId;
folder.ID = providerInfo.RootFolderId;
folder.CreateBy = providerInfo.Owner;
folder.CreateOn = providerInfo.CreateOn;
folder.FolderType = FolderType.DEFAULT;
folder.ModifiedBy = providerInfo.Owner;
folder.ModifiedOn = providerInfo.CreateOn;
folder.ProviderId = providerInfo.ID;
folder.ProviderKey = providerInfo.ProviderKey;
folder.RootFolderCreator = providerInfo.Owner;
folder.RootFolderId = providerInfo.RootFolderId;
folder.RootFolderType = providerInfo.RootFolderType;
folder.Shareable = false;
folder.Title = providerInfo.CustomerTitle;
folder.TotalFiles = 0;
folder.TotalSubFolders = 0;
return folder;
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
public List<Folder> GetBreadCrumbs(object folderId)
2020-01-27 11:15:18 +00:00
{
2020-02-14 10:45:46 +00:00
return BreadCrumbsManager.GetBreadCrumbs(folderId);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
public List<Folder> GetBreadCrumbs(object folderId, IFolderDao folderDao)
2020-01-27 11:15:18 +00:00
{
2020-02-14 10:45:46 +00:00
return BreadCrumbsManager.GetBreadCrumbs(folderId, folderDao);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
public void SetFileStatus(File file)
2020-01-27 11:15:18 +00:00
{
if (file == null || file.ID == null) return;
SetFileStatus(new List<File>(1) { file });
}
2020-02-05 08:30:04 +00:00
public void SetFileStatus(IEnumerable<File> files)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var tagDao = DaoFactory.TagDao;
var tagsNew = tagDao.GetNewTags(AuthContext.CurrentAccount.ID, files);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var tagsLocked = tagDao.GetTags(TagType.Locked, files.ToArray());
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
foreach (var file in files)
{
if (tagsNew.Any(r => r.EntryId.Equals(file.ID)))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
file.IsNew = true;
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var tagLocked = tagsLocked.FirstOrDefault(t => t.EntryId.Equals(file.ID));
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var lockedBy = tagLocked != null ? tagLocked.Owner : Guid.Empty;
file.Locked = lockedBy != Guid.Empty;
file.LockedBy = lockedBy != Guid.Empty && lockedBy != AuthContext.CurrentAccount.ID
? Global.GetUserName(lockedBy)
: null;
2020-01-27 11:15:18 +00:00
}
}
2020-02-05 08:30:04 +00:00
public bool FileLockedForMe(object fileId, Guid userId = default)
2020-01-27 11:15:18 +00:00
{
2020-02-13 12:19:25 +00:00
return LockerManager.FileLockedForMe(fileId, userId);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
public Guid FileLockedBy(object fileId, ITagDao tagDao)
2020-01-27 11:15:18 +00:00
{
2020-02-13 12:19:25 +00:00
return LockerManager.FileLockedBy(fileId, tagDao);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
public File SaveEditing(string fileId, string fileExtension, string downloadUri, Stream stream, string doc, string comment = null, bool checkRight = true, bool encrypted = false, ForcesaveType? forcesave = null)
2020-01-27 11:15:18 +00:00
{
var newExtension = string.IsNullOrEmpty(fileExtension)
? FileUtility.GetFileExtension(downloadUri)
: fileExtension;
var app = ThirdPartySelector.GetAppByFileId(fileId);
if (app != null)
{
app.SaveFile(fileId, newExtension, downloadUri, stream);
return null;
}
2020-02-05 08:30:04 +00:00
var fileDao = DaoFactory.FileDao;
var editLink = FileShareLink.Check(doc, false, fileDao, out var file);
if (file == null)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
file = fileDao.GetFile(fileId);
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (file == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
var fileSecurity = FileSecurity;
if (checkRight && !editLink && (!(fileSecurity.CanEdit(file) || fileSecurity.CanReview(file)) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (checkRight && FileLockedForMe(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (checkRight && FileTracker.IsEditing(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile);
if (file.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var currentExt = file.ConvertedExtension;
if (string.IsNullOrEmpty(newExtension)) newExtension = FileUtility.GetInternalExtension(file.Title);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var replaceVersion = false;
if (file.Forcesave != ForcesaveType.None)
{
if (file.Forcesave == ForcesaveType.User && FilesSettingsHelper.StoreForcesave)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
file.Version++;
2020-01-27 11:15:18 +00:00
}
else
{
2020-02-05 08:30:04 +00:00
replaceVersion = true;
}
}
else
{
if (file.Version != 1)
{
file.VersionGroup++;
}
else
{
var storeTemplate = GlobalStore.GetStoreTemplate();
var path = FileConstant.NewDocPath + Thread.CurrentThread.CurrentCulture + "/";
if (!storeTemplate.IsDirectory(path))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
path = FileConstant.NewDocPath + "default/";
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
path += "new" + FileUtility.GetInternalExtension(file.Title);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
//todo: think about the criteria for saving after creation
if (file.ContentLength != storeTemplate.GetFileSize("", path))
{
file.VersionGroup++;
2020-01-27 11:15:18 +00:00
}
}
2020-02-05 08:30:04 +00:00
file.Version++;
}
2020-02-07 10:29:16 +00:00
file.Forcesave = forcesave ?? ForcesaveType.None;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (string.IsNullOrEmpty(comment))
comment = FilesCommonResource.CommentEdit;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
file.Encrypted = encrypted;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
file.ConvertedType = FileUtility.GetFileExtension(file.Title) != newExtension ? newExtension : null;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (file.ProviderEntry && !newExtension.Equals(currentExt))
{
if (FileUtility.ExtsConvertible.Keys.Contains(newExtension)
&& FileUtility.ExtsConvertible[newExtension].Contains(currentExt))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
if (stream != null)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
downloadUri = PathProvider.GetTempUrl(stream, newExtension);
downloadUri = DocumentServiceConnector.ReplaceCommunityAdress(downloadUri);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
var key = DocumentServiceConnector.GenerateRevisionId(downloadUri);
DocumentServiceConnector.GetConvertedUri(downloadUri, newExtension, currentExt, key, null, false, out downloadUri);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
stream = null;
}
else
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
file.ID = null;
file.Title = FileUtility.ReplaceFileExtension(file.Title, newExtension);
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
file.ConvertedType = null;
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
using (var tmpStream = new MemoryStream())
{
if (stream != null)
{
stream.CopyTo(tmpStream);
}
else
{
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (WorkContext.IsMono)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
var req = (HttpWebRequest)WebRequest.Create(downloadUri);
using (var editedFileStream = new ResponseStream(req.GetResponse()))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
editedFileStream.CopyTo(tmpStream);
2020-01-27 11:15:18 +00:00
}
}
2020-02-05 08:30:04 +00:00
tmpStream.Position = 0;
file.ContentLength = tmpStream.Length;
file.Comment = string.IsNullOrEmpty(comment) ? null : comment;
if (replaceVersion)
{
file = fileDao.ReplaceFileVersion(file, tmpStream);
}
else
{
file = fileDao.SaveFile(file, tmpStream);
}
2020-01-27 11:15:18 +00:00
}
FileMarker.MarkAsNew(file);
FileMarker.RemoveMarkAsNew(file);
return file;
}
2020-03-02 12:31:53 +00:00
public File<T> SaveEditing<T>(T fileId, string fileExtension, string downloadUri, Stream stream, string doc, string comment = null, bool checkRight = true, bool encrypted = false, ForcesaveType? forcesave = null)
{
var newExtension = string.IsNullOrEmpty(fileExtension)
? FileUtility.GetFileExtension(downloadUri)
: fileExtension;
var app = ThirdPartySelector.GetAppByFileId(fileId.ToString());
if (app != null)
{
app.SaveFile(fileId.ToString(), newExtension, downloadUri, stream);
return null;
}
var fileDao = DaoFactory.GetFileDao<T>();
var editLink = FileShareLink.Check<T>(doc, false, fileDao, out var file);
if (file == null)
{
file = fileDao.GetFile(fileId);
}
if (file == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
var fileSecurity = FileSecurity;
if (checkRight && !editLink && (!(fileSecurity.CanEdit(file) || fileSecurity.CanReview(file)) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (checkRight && FileLockedForMe(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (checkRight && FileTracker.IsEditing(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile);
if (file.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
var currentExt = file.ConvertedExtension;
if (string.IsNullOrEmpty(newExtension)) newExtension = FileUtility.GetInternalExtension(file.Title);
var replaceVersion = false;
if (file.Forcesave != ForcesaveType.None)
{
if (file.Forcesave == ForcesaveType.User && FilesSettingsHelper.StoreForcesave)
{
file.Version++;
}
else
{
replaceVersion = true;
}
}
else
{
if (file.Version != 1)
{
file.VersionGroup++;
}
else
{
var storeTemplate = GlobalStore.GetStoreTemplate();
var path = FileConstant.NewDocPath + Thread.CurrentThread.CurrentCulture + "/";
if (!storeTemplate.IsDirectory(path))
{
path = FileConstant.NewDocPath + "default/";
}
path += "new" + FileUtility.GetInternalExtension(file.Title);
//todo: think about the criteria for saving after creation
if (file.ContentLength != storeTemplate.GetFileSize("", path))
{
file.VersionGroup++;
}
}
file.Version++;
}
file.Forcesave = forcesave ?? ForcesaveType.None;
if (string.IsNullOrEmpty(comment))
comment = FilesCommonResource.CommentEdit;
file.Encrypted = encrypted;
file.ConvertedType = FileUtility.GetFileExtension(file.Title) != newExtension ? newExtension : null;
if (file.ProviderEntry && !newExtension.Equals(currentExt))
{
if (FileUtility.ExtsConvertible.Keys.Contains(newExtension)
&& FileUtility.ExtsConvertible[newExtension].Contains(currentExt))
{
if (stream != null)
{
downloadUri = PathProvider.GetTempUrl(stream, newExtension);
downloadUri = DocumentServiceConnector.ReplaceCommunityAdress(downloadUri);
}
var key = DocumentServiceConnector.GenerateRevisionId(downloadUri);
DocumentServiceConnector.GetConvertedUri(downloadUri, newExtension, currentExt, key, null, false, out downloadUri);
stream = null;
}
else
{
file.ID = default;
file.Title = FileUtility.ReplaceFileExtension(file.Title, newExtension);
}
file.ConvertedType = null;
}
using (var tmpStream = new MemoryStream())
{
if (stream != null)
{
stream.CopyTo(tmpStream);
}
else
{
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (WorkContext.IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
var req = (HttpWebRequest)WebRequest.Create(downloadUri);
using (var editedFileStream = new ResponseStream(req.GetResponse()))
{
editedFileStream.CopyTo(tmpStream);
}
}
tmpStream.Position = 0;
file.ContentLength = tmpStream.Length;
file.Comment = string.IsNullOrEmpty(comment) ? null : comment;
if (replaceVersion)
{
file = fileDao.ReplaceFileVersion(file, tmpStream);
}
else
{
file = fileDao.SaveFile(file, tmpStream);
}
}
FileMarker.MarkAsNew(file);
FileMarker.RemoveMarkAsNew(file);
return file;
}
2020-02-05 08:30:04 +00:00
public void TrackEditing(string fileId, Guid tabId, Guid userId, string doc, bool editingAlone = false)
2020-01-27 11:15:18 +00:00
{
bool checkRight;
if (FileTracker.GetEditingBy(fileId).Contains(userId))
{
checkRight = FileTracker.ProlongEditing(fileId, tabId, userId, editingAlone);
if (!checkRight) return;
}
bool editLink;
2020-02-05 08:30:04 +00:00
var fileDao = DaoFactory.FileDao;
editLink = FileShareLink.Check(doc, false, fileDao, out var file);
if (file == null)
file = fileDao.GetFile(fileId);
2020-01-27 11:15:18 +00:00
if (file == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
2020-02-05 08:30:04 +00:00
var fileSecurity = FileSecurity;
if (!editLink && (!fileSecurity.CanEdit(file, userId) && !fileSecurity.CanReview(file, userId) && !fileSecurity.CanFillForms(file, userId) && !fileSecurity.CanComment(file, userId) || UserManager.GetUsers(userId).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
2020-01-27 11:15:18 +00:00
if (FileLockedForMe(file.ID, userId)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (file.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
checkRight = FileTracker.ProlongEditing(fileId, tabId, userId, editingAlone);
if (checkRight)
{
FileTracker.ChangeRight(fileId, userId, false);
}
}
2020-02-05 08:30:04 +00:00
public File UpdateToVersionFile(object fileId, int version, string doc = null, bool checkRight = true)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var fileDao = DaoFactory.FileDao;
if (version < 1) throw new ArgumentNullException("version");
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var editLink = FileShareLink.Check(doc, false, fileDao, out var fromFile);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (fromFile == null)
fromFile = fileDao.GetFile(fileId);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (fromFile == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (fromFile.Version != version)
fromFile = fileDao.GetFile(fromFile.ID, Math.Min(fromFile.Version, version));
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (fromFile == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (checkRight && !editLink && (!FileSecurity.CanEdit(fromFile) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (FileLockedForMe(fromFile.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (checkRight && FileTracker.IsEditing(fromFile.ID)) throw new Exception(FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile);
if (fromFile.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
if (fromFile.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var exists = cache.Get<string>(UPDATE_LIST + fileId.ToString()) != null;
if (exists)
{
throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile);
}
else
{
cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2));
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
try
{
var currFile = fileDao.GetFile(fileId);
2020-02-10 16:04:54 +00:00
var newFile = ServiceProvider.GetService<File>();
newFile.ID = fromFile.ID;
newFile.Version = currFile.Version + 1;
newFile.VersionGroup = currFile.VersionGroup;
newFile.Title = FileUtility.ReplaceFileExtension(currFile.Title, FileUtility.GetFileExtension(fromFile.Title));
newFile.FileStatus = currFile.FileStatus;
newFile.FolderID = currFile.FolderID;
newFile.CreateBy = currFile.CreateBy;
newFile.CreateOn = currFile.CreateOn;
newFile.ModifiedBy = fromFile.ModifiedBy;
newFile.ModifiedOn = fromFile.ModifiedOn;
newFile.ConvertedType = fromFile.ConvertedType;
newFile.Comment = string.Format(FilesCommonResource.CommentRevert, fromFile.ModifiedOnString);
newFile.Encrypted = fromFile.Encrypted;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
using (var stream = fileDao.GetFileStream(fromFile))
{
newFile.ContentLength = stream.CanSeek ? stream.Length : fromFile.ContentLength;
newFile = fileDao.SaveFile(newFile, stream);
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
FileMarker.MarkAsNew(newFile);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
SetFileStatus(newFile);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
return newFile;
}
catch (Exception e)
{
Logger.Error(string.Format("Error on update {0} to version {1}", fileId, version), e);
throw new Exception(e.Message, e);
}
finally
{
cache.Remove(UPDATE_LIST + fromFile.ID);
2020-01-27 11:15:18 +00:00
}
}
2020-03-02 12:31:53 +00:00
public File<T> UpdateToVersionFile<T>(T fileId, int version, string doc = null, bool checkRight = true)
{
var fileDao = DaoFactory.GetFileDao<T>();
if (version < 1) throw new ArgumentNullException("version");
var editLink = FileShareLink.Check(doc, false, fileDao, out var fromFile);
if (fromFile == null)
fromFile = fileDao.GetFile(fileId);
if (fromFile == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (fromFile.Version != version)
fromFile = fileDao.GetFile(fromFile.ID, Math.Min(fromFile.Version, version));
if (fromFile == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (checkRight && !editLink && (!FileSecurity.CanEdit(fromFile) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (FileLockedForMe(fromFile.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (checkRight && FileTracker.IsEditing(fromFile.ID)) throw new Exception(FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile);
if (fromFile.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
if (fromFile.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
var exists = cache.Get<string>(UPDATE_LIST + fileId.ToString()) != null;
if (exists)
{
throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile);
}
else
{
cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2));
}
try
{
var currFile = fileDao.GetFile(fileId);
var newFile = ServiceProvider.GetService<File<T>>();
newFile.ID = fromFile.ID;
newFile.Version = currFile.Version + 1;
newFile.VersionGroup = currFile.VersionGroup;
newFile.Title = FileUtility.ReplaceFileExtension(currFile.Title, FileUtility.GetFileExtension(fromFile.Title));
newFile.FileStatus = currFile.FileStatus;
newFile.FolderID = currFile.FolderID;
newFile.CreateBy = currFile.CreateBy;
newFile.CreateOn = currFile.CreateOn;
newFile.ModifiedBy = fromFile.ModifiedBy;
newFile.ModifiedOn = fromFile.ModifiedOn;
newFile.ConvertedType = fromFile.ConvertedType;
newFile.Comment = string.Format(FilesCommonResource.CommentRevert, fromFile.ModifiedOnString);
newFile.Encrypted = fromFile.Encrypted;
using (var stream = fileDao.GetFileStream(fromFile))
{
newFile.ContentLength = stream.CanSeek ? stream.Length : fromFile.ContentLength;
newFile = fileDao.SaveFile(newFile, stream);
}
FileMarker.MarkAsNew(newFile);
SetFileStatus(newFile);
return newFile;
}
catch (Exception e)
{
Logger.Error(string.Format("Error on update {0} to version {1}", fileId, version), e);
throw new Exception(e.Message, e);
}
finally
{
cache.Remove(UPDATE_LIST + fromFile.ID);
}
}
2020-02-05 08:30:04 +00:00
public File CompleteVersionFile(object fileId, int version, bool continueVersion, bool checkRight = true)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var fileDao = DaoFactory.FileDao;
var fileVersion = version > 0
? fileDao.GetFile(fileId, version)
: fileDao.GetFile(fileId);
if (fileVersion == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (checkRight && (!FileSecurity.CanEdit(fileVersion) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (FileLockedForMe(fileVersion.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (fileVersion.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
if (fileVersion.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var lastVersionFile = fileDao.GetFile(fileVersion.ID);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
if (continueVersion)
{
if (lastVersionFile.VersionGroup > 1)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
fileDao.ContinueVersion(fileVersion.ID, fileVersion.Version);
lastVersionFile.VersionGroup--;
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
}
else
{
if (!FileTracker.IsEditing(lastVersionFile.ID))
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
if (fileVersion.Version == lastVersionFile.Version)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
lastVersionFile = UpdateToVersionFile(fileVersion.ID, fileVersion.Version, null, checkRight);
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
fileDao.CompleteVersion(fileVersion.ID, fileVersion.Version);
lastVersionFile.VersionGroup++;
2020-01-27 11:15:18 +00:00
}
2020-02-05 08:30:04 +00:00
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
SetFileStatus(lastVersionFile);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
return lastVersionFile;
2020-01-27 11:15:18 +00:00
}
2020-03-02 12:31:53 +00:00
public File<T> CompleteVersionFile<T>(T fileId, int version, bool continueVersion, bool checkRight = true)
{
var fileDao = DaoFactory.GetFileDao<T>();
var fileVersion = version > 0
? fileDao.GetFile(fileId, version)
: fileDao.GetFile(fileId);
if (fileVersion == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (checkRight && (!FileSecurity.CanEdit(fileVersion) || UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager))) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (FileLockedForMe(fileVersion.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (fileVersion.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
if (fileVersion.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
var lastVersionFile = fileDao.GetFile(fileVersion.ID);
if (continueVersion)
{
if (lastVersionFile.VersionGroup > 1)
{
fileDao.ContinueVersion(fileVersion.ID, fileVersion.Version);
lastVersionFile.VersionGroup--;
}
}
else
{
if (!FileTracker.IsEditing(lastVersionFile.ID))
{
if (fileVersion.Version == lastVersionFile.Version)
{
lastVersionFile = UpdateToVersionFile(fileVersion.ID, fileVersion.Version, null, checkRight);
}
fileDao.CompleteVersion(fileVersion.ID, fileVersion.Version);
lastVersionFile.VersionGroup++;
}
}
SetFileStatus(lastVersionFile);
return lastVersionFile;
}
2020-02-05 08:30:04 +00:00
public bool FileRename(object fileId, string title, out File file)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var fileDao = DaoFactory.FileDao;
file = fileDao.GetFile(fileId);
if (file == null) throw new FileNotFoundException(FilesCommonResource.ErrorMassage_FileNotFound);
if (!FileSecurity.CanEdit(file)) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_RenameFile);
if (!FileSecurity.CanDelete(file) && UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsVisitor(UserManager)) throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_RenameFile);
if (FileLockedForMe(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_LockedFile);
if (file.ProviderEntry && FileTracker.IsEditing(file.ID)) throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile);
if (file.RootFolderType == FolderType.TRASH) throw new Exception(FilesCommonResource.ErrorMassage_ViewTrashItem);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
title = Global.ReplaceInvalidCharsAndTruncate(title);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var ext = FileUtility.GetFileExtension(file.Title);
if (string.Compare(ext, FileUtility.GetFileExtension(title), true) != 0)
{
title += ext;
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var fileAccess = file.Access;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
var renamed = false;
if (string.Compare(file.Title, title, false) != 0)
{
var newFileID = fileDao.FileRename(file, title);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
file = fileDao.GetFile(newFileID);
file.Access = fileAccess;
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
DocumentServiceHelper.RenameFile(file, fileDao);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
renamed = true;
}
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
SetFileStatus(file);
2020-01-27 11:15:18 +00:00
2020-02-05 08:30:04 +00:00
return renamed;
2020-01-27 11:15:18 +00:00
}
//Long operation
2020-02-05 08:30:04 +00:00
public void DeleteSubitems(object parentId, IFolderDao folderDao, IFileDao fileDao)
2020-01-27 11:15:18 +00:00
{
var folders = folderDao.GetFolders(parentId);
foreach (var folder in folders)
{
DeleteSubitems(folder.ID, folderDao, fileDao);
2020-02-05 08:30:04 +00:00
Logger.InfoFormat("Delete folder {0} in {1}", folder.ID, parentId);
2020-01-27 11:15:18 +00:00
folderDao.DeleteFolder(folder.ID);
}
var files = fileDao.GetFiles(parentId, null, FilterType.None, false, Guid.Empty, string.Empty, true);
foreach (var file in files)
{
2020-02-05 08:30:04 +00:00
Logger.InfoFormat("Delete file {0} in {1}", file.ID, parentId);
2020-01-27 11:15:18 +00:00
fileDao.DeleteFile(file.ID);
}
}
2020-03-02 12:31:53 +00:00
public void DeleteSubitems<T>(T parentId, IFolderDao<T> folderDao, IFileDao<T> fileDao)
{
var folders = folderDao.GetFolders(parentId);
foreach (var folder in folders)
{
DeleteSubitems<T>(folder.ID, folderDao, fileDao);
Logger.InfoFormat("Delete folder {0} in {1}", folder.ID, parentId);
folderDao.DeleteFolder(folder.ID);
}
var files = fileDao.GetFiles(parentId, null, FilterType.None, false, Guid.Empty, string.Empty, true);
foreach (var file in files)
{
Logger.InfoFormat("Delete file {0} in {1}", file.ID, parentId);
fileDao.DeleteFile(file.ID);
}
}
2020-02-05 08:30:04 +00:00
public void MoveSharedItems(object parentId, object toId, IFolderDao folderDao, IFileDao fileDao)
2020-01-27 11:15:18 +00:00
{
2020-02-05 08:30:04 +00:00
var fileSecurity = FileSecurity;
2020-01-27 11:15:18 +00:00
var folders = folderDao.GetFolders(parentId);
foreach (var folder in folders)
{
var shared = folder.Shared
&& fileSecurity.GetShares(folder).Any(record => record.Share != FileShare.Restrict);
if (shared)
{
2020-02-05 08:30:04 +00:00
Logger.InfoFormat("Move shared folder {0} from {1} to {2}", folder.ID, parentId, toId);
2020-01-27 11:15:18 +00:00
folderDao.MoveFolder(folder.ID, toId, null);
}
else
{
MoveSharedItems(folder.ID, toId, folderDao, fileDao);
}
}
var files = fileDao.GetFiles(parentId, null, FilterType.None, false, Guid.Empty, string.Empty, true);
foreach (var file
in files.Where(file =>
file.Shared
&& fileSecurity.GetShares(file)
.Any(record =>
record.Subject != FileConstant.ShareLinkId
&& record.Share != FileShare.Restrict)))
{
2020-02-05 08:30:04 +00:00
Logger.InfoFormat("Move shared file {0} from {1} to {2}", file.ID, parentId, toId);
2020-01-27 11:15:18 +00:00
fileDao.MoveFile(file.ID, toId);
}
}
2020-03-02 12:31:53 +00:00
public void MoveSharedItems<T>(T parentId, T toId, IFolderDao<T> folderDao, IFileDao<T> fileDao)
{
var fileSecurity = FileSecurity;
var folders = folderDao.GetFolders(parentId);
foreach (var folder in folders)
{
var shared = folder.Shared
&& fileSecurity.GetShares(folder).Any(record => record.Share != FileShare.Restrict);
if (shared)
{
Logger.InfoFormat("Move shared folder {0} from {1} to {2}", folder.ID, parentId, toId);
folderDao.MoveFolder(folder.ID, toId, null);
}
else
{
MoveSharedItems(folder.ID, toId, folderDao, fileDao);
}
}
var files = fileDao.GetFiles(parentId, null, FilterType.None, false, Guid.Empty, string.Empty, true);
foreach (var file
in files.Where(file =>
file.Shared
&& fileSecurity.GetShares(file)
.Any(record =>
record.Subject != FileConstant.ShareLinkId
&& record.Share != FileShare.Restrict)))
{
Logger.InfoFormat("Move shared file {0} from {1} to {2}", file.ID, parentId, toId);
fileDao.MoveFile(file.ID, toId);
}
}
public static void ReassignItems<T>(T parentId, Guid fromUserId, Guid toUserId, IFolderDao<T> folderDao, IFileDao<T> fileDao)
2020-01-27 11:15:18 +00:00
{
var fileIds = fileDao.GetFiles(parentId, new OrderBy(SortedByType.AZ, true), FilterType.ByUser, false, fromUserId, null, true, true)
.Where(file => file.CreateBy == fromUserId).Select(file => file.ID);
fileDao.ReassignFiles(fileIds.ToArray(), toUserId);
var folderIds = folderDao.GetFolders(parentId, new OrderBy(SortedByType.AZ, true), FilterType.ByUser, false, fromUserId, null, true)
.Where(folder => folder.CreateBy == fromUserId).Select(folder => folder.ID);
folderDao.ReassignFolders(folderIds.ToArray(), toUserId);
}
}
2020-02-13 12:19:25 +00:00
public static class EntryManagerExtension
{
2020-02-17 08:58:14 +00:00
public static DIHelper AddEntryManagerService(this DIHelper services)
2020-02-13 12:19:25 +00:00
{
services.TryAddScoped<EntryManager>();
return services
.AddDaoFactoryService()
.AddFileSecurityService()
.AddGlobalFolderHelperService()
.AddPathProviderService()
.AddAuthContextService()
.AddFileMarkerService()
.AddFileUtilityService()
.AddGlobalService()
.AddGlobalStoreService()
.AddCoreBaseSettingsService()
.AddFilesSettingsHelperService()
.AddUserManagerService()
.AddFileShareLinkService()
.AddDocumentServiceConnectorService()
.AddDocumentServiceHelperService()
.AddFilesIntegrationService()
.AddThirdpartyConfigurationService()
.AddLockerManagerService()
2020-02-14 10:45:46 +00:00
.AddBreadCrumbsManagerService()
2020-02-13 12:19:25 +00:00
;
}
}
public static class LockerManagerExtension
{
2020-02-17 08:58:14 +00:00
public static DIHelper AddLockerManagerService(this DIHelper services)
2020-02-13 12:19:25 +00:00
{
services.TryAddScoped<LockerManager>();
return services
.AddAuthContextService()
.AddDaoFactoryService();
}
}
2020-02-14 10:45:46 +00:00
public static class BreadCrumbsManagerExtension
{
2020-02-17 08:58:14 +00:00
public static DIHelper AddBreadCrumbsManagerService(this DIHelper services)
2020-02-14 10:45:46 +00:00
{
services.TryAddScoped<BreadCrumbsManager>();
return services
.AddDaoFactoryService()
.AddFileSecurityService()
.AddGlobalFolderHelperService()
.AddAuthContextService();
}
}
2020-01-27 11:15:18 +00:00
}