Merge branch 'develop' into bugfix/login-fix

This commit is contained in:
Ilya Oleshko 2020-12-07 09:52:04 +03:00
commit 83466bd638
27 changed files with 289 additions and 358 deletions

View File

@ -98,13 +98,24 @@ namespace ASC.Common.Threading
public T GetProperty<T>(string name)
{
if (!DistributedTaskCache.Props.Any(r => r.Key == name)) return default;
var val = DistributedTaskCache.Props.SingleOrDefault(r => r.Key == name);
var val = DistributedTaskCache.Props.FirstOrDefault(r => r.Key == name);
if (val == null) return default;
var resType = typeof(T);
object result = val.Value;
if(resType == typeof(Guid))
{
result = Guid.Parse(val.Value.Trim('"'));
}
else if(resType.IsEnum)
{
Enum.TryParse(resType, val.Value, out var e);
result = e;
}
return JsonSerializer.Deserialize<T>(val.Value);
return (T)Convert.ChangeType(result, resType);
}
public void SetProperty(string name, object value)

View File

@ -164,6 +164,7 @@ namespace ASC.Core.Data
var counter = CoreDbContext.QuotaRows
.Where(r => r.Path == row.Path && r.Tenant == row.Tenant)
.Select(r => r.Counter)
.Take(1)
.FirstOrDefault();
var dbQuotaRow = new DbQuotaRow

View File

@ -1,63 +0,0 @@
/*
*
* (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 ASC.Common.Caching;
namespace ASC.Data.Storage
{
static class DataStoreCache
{
private static readonly ICache Cache = AscCache.Memory;
public static void Put(IDataStore store, string tenantId, string module)
{
Cache.Insert(DataStoreCacheItemExtenstion.MakeCacheKey(tenantId, module), store, DateTime.MaxValue);
}
public static IDataStore Get(string tenantId, string module)
{
return Cache.Get<IDataStore>(DataStoreCacheItemExtenstion.MakeCacheKey(tenantId, module));
}
public static void Remove(string tenantId, string module)
{
Cache.Remove(DataStoreCacheItemExtenstion.MakeCacheKey(tenantId, module));
}
}
public static class DataStoreCacheItemExtenstion
{
internal static string MakeCacheKey(string tenantId, string module)
{
return string.Format("{0}:\\{1}", tenantId, module);
}
}
}

View File

@ -29,6 +29,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Data.Storage.Configuration;
@ -40,6 +41,7 @@ using Microsoft.Extensions.Options;
namespace ASC.Data.Storage.DiscStorage
{
[Scope]
public class DiscDataStore : BaseStorage
{
private readonly Dictionary<string, MappedPath> _mappedPaths = new Dictionary<string, MappedPath>();

View File

@ -37,6 +37,7 @@ using System.Text;
using System.Threading;
using System.Web;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Data.Storage.Configuration;
@ -55,6 +56,7 @@ using MimeMapping = ASC.Common.Web.MimeMapping;
namespace ASC.Data.Storage.GoogleCloud
{
[Scope]
public class GoogleCloudStorage : BaseStorage
{
private string _subDir = string.Empty;
@ -241,7 +243,7 @@ namespace ASC.Data.Storage.GoogleCloud
{
var contentDisposition = string.Format("attachment; filename={0};",
HttpUtility.UrlPathEncode(attachmentFileName));
if (attachmentFileName.Any(c => (int)c >= 0 && (int)c <= 127))
if (attachmentFileName.Any(c => c >= 0 && c <= 127))
{
contentDisposition = string.Format("attachment; filename*=utf-8''{0};",
HttpUtility.UrlPathEncode(attachmentFileName));
@ -786,7 +788,7 @@ namespace ASC.Data.Storage.GoogleCloud
continue;
}
if ((int)status != 308)
if (status != 308)
throw (ex);
break;

View File

@ -30,6 +30,7 @@ using System.IO;
using System.Linq;
using System.Web;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Data.Storage.Configuration;
@ -45,6 +46,7 @@ using MimeMapping = ASC.Common.Web.MimeMapping;
namespace ASC.Data.Storage.RackspaceCloud
{
[Scope]
public class RackspaceCloudStorage : BaseStorage
{
private string _region;
@ -248,7 +250,7 @@ namespace ASC.Data.Storage.RackspaceCloud
{
var contentDisposition = string.Format("attachment; filename={0};",
HttpUtility.UrlPathEncode(attachmentFileName));
if (attachmentFileName.Any(c => (int)c >= 0 && (int)c <= 127))
if (attachmentFileName.Any(c => c >= 0 && c <= 127))
{
contentDisposition = string.Format("attachment; filename*=utf-8''{0};",
HttpUtility.UrlPathEncode(attachmentFileName));

View File

@ -41,6 +41,7 @@ using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Amazon.Util;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Data.Storage.Configuration;
@ -53,6 +54,7 @@ using MimeMapping = ASC.Common.Web.MimeMapping;
namespace ASC.Data.Storage.S3
{
[Scope]
public class S3Storage : BaseStorage
{
private readonly List<string> _domains = new List<string>();
@ -190,7 +192,7 @@ namespace ASC.Data.Storage.S3
{
var contentDisposition = string.Format("attachment; filename={0};",
HttpUtility.UrlPathEncode(attachmentFileName));
if (attachmentFileName.Any(c => (int)c >= 0 && (int)c <= 127))
if (attachmentFileName.Any(c => c >= 0 && c <= 127))
{
contentDisposition = string.Format("attachment; filename*=utf-8''{0};",
HttpUtility.UrlPathEncode(attachmentFileName));

View File

@ -29,50 +29,20 @@ using System.Collections.Generic;
using System.Linq;
using ASC.Common;
using ASC.Common.Caching;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Common.Configuration;
using ASC.Core.Common.Settings;
using ASC.Data.Storage.Configuration;
using ASC.Data.Storage.DiscStorage;
using ASC.Data.Storage.Encryption;
using ASC.Security.Cryptography;
using ASC.Data.Storage.GoogleCloud;
using ASC.Data.Storage.RackspaceCloud;
using ASC.Data.Storage.S3;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace ASC.Data.Storage
{
[Singletone]
public class StorageFactoryListener
{
private volatile bool Subscribed;
private readonly object locker;
private ICacheNotify<DataStoreCacheItem> Cache { get; }
public StorageFactoryListener(ICacheNotify<DataStoreCacheItem> cache)
{
Cache = cache;
locker = new object();
}
public void Subscribe()
{
if (Subscribed) return;
lock (locker)
{
if (Subscribed) return;
Subscribed = true;
Cache.Subscribe((r) => DataStoreCache.Remove(r.TenantId, r.Module), CacheNotifyAction.Remove);
}
}
}
[Singletone(Additional = typeof(StorageConfigExtension))]
public class StorageFactoryConfig
{
@ -174,7 +144,7 @@ namespace ASC.Data.Storage
}
}
[Scope]
[Scope(Additional = typeof(StorageFactoryExtension))]
public class StorageFactory
{
private const string DefaultTenantName = "default";
@ -184,55 +154,22 @@ namespace ASC.Data.Storage
private StorageSettingsHelper StorageSettingsHelper { get; }
private TenantManager TenantManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private PathUtils PathUtils { get; }
private EmailValidationKeyProvider EmailValidationKeyProvider { get; }
private IOptionsMonitor<ILog> Options { get; }
private IHttpContextAccessor HttpContextAccessor { get; }
private EncryptionSettingsHelper EncryptionSettingsHelper { get; }
private EncryptionFactory EncryptionFactory { get; }
private IServiceProvider ServiceProvider { get; }
public StorageFactory(
StorageFactoryListener storageFactoryListener,
IServiceProvider serviceProvider,
StorageFactoryConfig storageFactoryConfig,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper,
TenantManager tenantManager,
CoreBaseSettings coreBaseSettings,
PathUtils pathUtils,
EmailValidationKeyProvider emailValidationKeyProvider,
IOptionsMonitor<ILog> options,
EncryptionSettingsHelper encryptionSettingsHelper,
EncryptionFactory encryptionFactory) :
this(storageFactoryListener, storageFactoryConfig, settingsManager, storageSettingsHelper, tenantManager, coreBaseSettings, pathUtils, emailValidationKeyProvider, options, null, encryptionSettingsHelper, encryptionFactory)
CoreBaseSettings coreBaseSettings)
{
}
public StorageFactory(
StorageFactoryListener storageFactoryListener,
StorageFactoryConfig storageFactoryConfig,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper,
TenantManager tenantManager,
CoreBaseSettings coreBaseSettings,
PathUtils pathUtils,
EmailValidationKeyProvider emailValidationKeyProvider,
IOptionsMonitor<ILog> options,
IHttpContextAccessor httpContextAccessor,
EncryptionSettingsHelper encryptionSettingsHelper,
EncryptionFactory encryptionFactory)
{
storageFactoryListener.Subscribe();
ServiceProvider = serviceProvider;
StorageFactoryConfig = storageFactoryConfig;
SettingsManager = settingsManager;
StorageSettingsHelper = storageSettingsHelper;
TenantManager = tenantManager;
CoreBaseSettings = coreBaseSettings;
PathUtils = pathUtils;
EmailValidationKeyProvider = emailValidationKeyProvider;
Options = options;
HttpContextAccessor = httpContextAccessor;
EncryptionSettingsHelper = encryptionSettingsHelper;
EncryptionFactory = encryptionFactory;
}
public IDataStore GetStorage(string tenant, string module)
@ -261,10 +198,6 @@ namespace ASC.Data.Storage
//Make tennant path
tenant = TenantPath.CreatePath(tenant);
//remove cache
//var store = DataStoreCache.Get(tenant, module);//TODO
//if (store == null)
//{
var section = StorageFactoryConfig.Section;
if (section == null)
{
@ -273,7 +206,6 @@ namespace ASC.Data.Storage
var settings = SettingsManager.LoadForTenant<StorageSettings>(tenantId);
//}
return GetDataStore(tenant, module, StorageSettingsHelper.DataStoreConsumer(settings), controller);
}
@ -294,16 +226,6 @@ namespace ASC.Data.Storage
return GetDataStore(tenant, module, consumer, new TenantQuotaController(tenantId, TenantManager));
}
private IDataStore GetStoreAndCache(string tenant, string module, DataStoreConsumer consumer, IQuotaController controller)
{
var store = GetDataStore(tenant, module, consumer, controller);
if (store != null)
{
DataStoreCache.Put(store, tenant, module);
}
return store;
}
private IDataStore GetDataStore(string tenant, string module, DataStoreConsumer consumer, IQuotaController controller)
{
var storage = StorageFactoryConfig.Section;
@ -330,10 +252,22 @@ namespace ASC.Data.Storage
props = handler.Property.ToDictionary(r => r.Name, r => r.Value);
}
return ((IDataStore)Activator.CreateInstance(instanceType, TenantManager, PathUtils, EmailValidationKeyProvider, HttpContextAccessor, Options, EncryptionSettingsHelper, EncryptionFactory))
;
return ((IDataStore)ActivatorUtilities.CreateInstance(ServiceProvider, instanceType))
.Configure(tenant, handler, moduleElement, props)
.SetQuotaController(moduleElement.Count ? controller : null
/*don't count quota if specified on module*/);
}
}
public class StorageFactoryExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<DiscDataStore>();
services.TryAdd<GoogleCloudStorage>();
services.TryAdd<RackspaceCloudStorage>();
services.TryAdd<S3Storage>();
}
}
}

View File

@ -1686,7 +1686,11 @@ class SectionBodyContent extends React.Component {
) : (
<Consumer>
{(context) => (
<RowContainer draggable useReactWindow={false}>
<RowContainer
className="files-row-container"
draggable
useReactWindow={false}
>
{items.map((item) => {
const { checked, isFolder, value, contextOptions } = item;
const sectionWidth = context.sectionWidth;

View File

@ -236,13 +236,17 @@ class NewFilesPanelComponent extends React.Component {
<Backdrop onClick={onClose} visible={visible} zIndex={zIndex} />
<Aside className="header_aside-panel" visible={visible}>
<StyledContent>
<StyledHeaderContent className="files-operations-panel">
<Heading size="medium" truncate>
<StyledHeaderContent>
<Heading
className="files-operations-header"
size="medium"
truncate
>
{t("NewFiles")}
</Heading>
</StyledHeaderContent>
<StyledBody className="files-operations-body">
<RowContainer useReactWindow manualHeight="83vh">
<RowContainer useReactWindow manualHeight="87vh">
{files.map((file) => {
const element = this.getItemIcon(file);
return (

View File

@ -23,7 +23,7 @@ import {
StyledAsidePanel,
StyledContent,
StyledFooter,
StyledSharingHeaderContent,
StyledHeaderContent,
StyledSharingBody,
} from "../StyledPanels";
import { AddUsersPanel, AddGroupsPanel, EmbeddingPanel } from "../index";
@ -593,7 +593,7 @@ class SharingPanelComponent extends React.Component {
<Backdrop onClick={this.onClose} visible={visible} zIndex={zIndex} />
<Aside className="header_aside-panel" visible={visible}>
<StyledContent>
<StyledSharingHeaderContent>
<StyledHeaderContent>
<Heading className="sharing_panel-header" size="medium" truncate>
{t("SharingSettingsTitle")}
</Heading>
@ -631,12 +631,8 @@ class SharingPanelComponent extends React.Component {
onClick={this.onKeyClick}
/>*/}
</div>
</StyledSharingHeaderContent>
<StyledSharingBody
ref={this.scrollRef}
stype="mediumBlack"
style={{ height: `calc(100vh - 157px)` }}
>
</StyledHeaderContent>
<StyledSharingBody ref={this.scrollRef} stype="mediumBlack">
{shareDataItems.map((item, index) => (
<SharingRow
key={index}

View File

@ -29,10 +29,7 @@ const PanelStyles = css`
const StyledAsidePanel = styled.div`
z-index: 310;
.sharing_panel-header {
font-weight: 700;
margin: 14px 0;
}
.modal-dialog-aside {
padding: 0;
transform: translateX(${(props) => (props.visible ? "0" : "500px")});
@ -110,10 +107,6 @@ const StyledContent = styled.div`
background-color: #fff;
padding: 0 16px;
.files-operations-panel {
border-bottom: 1px solid #dee2e6;
}
.header_aside-panel-header {
max-width: 500px;
margin: 0 0 0 16px;
@ -129,6 +122,28 @@ const StyledContent = styled.div`
const StyledHeaderContent = styled.div`
display: flex;
align-items: center;
.sharing_panel-icons-container {
display: flex;
margin-left: auto;
.sharing_panel-drop-down-wrapper {
position: relative;
.sharing_panel-drop-down {
padding: 4px 0;
}
.sharing_panel-plus-icon {
//margin-right: 12px;
}
}
}
.files-operations-header,
.sharing_panel-header {
font-weight: 700;
margin: 14px 0;
}
`;
const StyledBody = styled.div`
@ -212,31 +227,10 @@ const StyledBody = styled.div`
}
`;
const StyledSharingHeaderContent = styled.div`
display: flex;
align-items: center;
border-bottom: 1px solid #dee2e6;
.sharing_panel-icons-container {
display: flex;
margin-left: auto;
.sharing_panel-drop-down-wrapper {
position: relative;
.sharing_panel-drop-down {
padding: 4px 0;
}
.sharing_panel-plus-icon {
//margin-right: 12px;
}
}
}
`;
const StyledSharingBody = styled(Scrollbar)`
position: relative;
padding: 16px 0;
height: calc(100vh - 157px) !important;
.row_content {
overflow: visible;
@ -366,7 +360,6 @@ export {
StyledContent,
StyledHeaderContent,
StyledBody,
StyledSharingHeaderContent,
StyledSharingBody,
StyledFooter,
};

View File

@ -110,7 +110,7 @@ namespace ASC.Web.Files.Core.Entries
if (!FileSecurity.CanEdit(file)) throw new System.Security.SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
if (file.RootFolderType != FolderType.Privacy) throw new NotSupportedException();
var fileShares = FileStorageService.GetSharedInfo(new ItemList<string> { string.Format("file_{0}", fileId) }).ToList();
var fileShares = FileStorageService.GetSharedInfo(new List<T> { fileId }, new List<T> { }).ToList();
fileShares = fileShares.Where(share => !share.SubjectGroup
&& !share.SubjectId.Equals(FileConstant.ShareLinkId)
&& share.Share == FileShare.ReadWrite).ToList();

View File

@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@ -1745,37 +1744,40 @@ namespace ASC.Web.Files.Services.WCFService
#endregion
public ItemList<AceWrapper> GetSharedInfo(ItemList<string> objectIds)
public ItemList<AceWrapper> GetSharedInfo(IEnumerable<T> fileIds, IEnumerable<T> folderIds)
{
return FileSharing.GetSharedInfo<T>(objectIds);
return FileSharing.GetSharedInfo(fileIds, folderIds);
}
public ItemList<AceShortWrapper> GetSharedInfoShort(string objectId)
public ItemList<AceShortWrapper> GetSharedInfoShortFile(T fileId)
{
return FileSharing.GetSharedInfoShort<T>(objectId);
return FileSharing.GetSharedInfoShortFile(fileId);
}
public ItemList<string> SetAceObject(AceCollection aceCollection, bool notify)
public ItemList<AceShortWrapper> GetSharedInfoShortFolder(T folderId)
{
return FileSharing.GetSharedInfoShortFolder(folderId);
}
public List<T> SetAceObject(AceCollection<T> aceCollection, bool notify)
{
var fileDao = GetFileDao();
var folderDao = GetFolderDao();
var result = new ItemList<string>();
foreach (var objectId in aceCollection.Entries)
{
Debug.Assert(objectId != null, "objectId != null");
var entryType = objectId.StartsWith("file_") ? FileEntryType.File : FileEntryType.Folder;
var entryId = (T)Convert.ChangeType(objectId.Substring((entryType == FileEntryType.File ? "file_" : "folder_").Length), typeof(T));
var entry = entryType == FileEntryType.File
? fileDao.GetFile(entryId)
: (FileEntry<T>)folderDao.GetFolder(entryId);
var result = new List<T>();
var entries = new List<FileEntry<T>>();
entries.AddRange(aceCollection.Files.Select(fileId => fileDao.GetFile(fileId)));
entries.AddRange(aceCollection.Folders.Select(folderDao.GetFolder));
foreach (var entry in entries)
{
try
{
var changed = FileSharingAceHelper.SetAceObject(aceCollection.Aces, entry, notify, aceCollection.Message);
if (changed)
{
FilesMessageService.Send(entry, GetHttpHeaders(),
entryType == FileEntryType.Folder ? MessageAction.FolderUpdatedAccess : MessageAction.FileUpdatedAccess,
entry.FileEntryType == FileEntryType.Folder ? MessageAction.FolderUpdatedAccess : MessageAction.FileUpdatedAccess,
entry.Title);
}
}
@ -1785,9 +1787,9 @@ namespace ASC.Web.Files.Services.WCFService
}
var securityDao = GetSecurityDao();
if (securityDao.IsShared(entry.ID, entryType))
if (securityDao.IsShared(entry.ID, entry.FileEntryType))
{
result.Add(objectId);
result.Add(entry.ID);
}
}
return result;
@ -1987,7 +1989,7 @@ namespace ASC.Web.Files.Services.WCFService
NotifyClient.SendEditorMentions(file, fileLink, recipients, message);
return showSharingSettings ? GetSharedInfoShort("file_" + fileId) : null;
return showSharingSettings ? GetSharedInfoShortFile(fileId) : null;
}
public ItemList<EncryptionKeyPair> GetEncryptionAccess(T fileId)
@ -2027,14 +2029,12 @@ namespace ASC.Web.Files.Services.WCFService
//return new ItemList<string>(accounts);
}
public ItemList<FileEntry<T>> ChangeOwner(ItemList<string> items, Guid userId)
public IEnumerable<FileEntry> ChangeOwner(IEnumerable<T> foldersId, IEnumerable<T> filesId, Guid userId)
{
var userInfo = UserManager.GetUsers(userId);
ErrorIf(Equals(userInfo, Constants.LostUser) || userInfo.IsVisitor(UserManager), FilesCommonResource.ErrorMassage_ChangeOwner);
ParseArrayItems(items, out var foldersId, out var filesId);
var entries = new List<FileEntry<T>>();
var entries = new List<FileEntry>();
var folderDao = GetFolderDao();
var folders = folderDao.GetFolders(foldersId);
@ -2103,7 +2103,7 @@ namespace ASC.Web.Files.Services.WCFService
entries.Add(newFile);
}
return new ItemList<FileEntry<T>>(entries);
return entries;
}
public bool StoreOriginal(bool set)
@ -2224,18 +2224,6 @@ namespace ASC.Web.Files.Services.WCFService
return DaoFactory.GetSecurityDao<T>();
}
private static void ParseArrayItems(IEnumerable<string> data, out List<T> foldersId, out List<T> filesId)
{
//TODO:!!!!Fix
foldersId = new List<T>();
filesId = new List<T>();
foreach (var id in data)
{
if (id.StartsWith("file_")) filesId.Add((T)Convert.ChangeType(id.Substring("file_".Length), typeof(T)));
if (id.StartsWith("folder_")) foldersId.Add((T)Convert.ChangeType(id.Substring("folder_".Length), typeof(T)));
}
}
private static void ErrorIf(bool condition, string errorMessage)
{
if (condition) throw new InvalidOperationException(errorMessage);

View File

@ -0,0 +1,12 @@
using System;
using System.Text.Json;
using ASC.Files.Model;
namespace ASC.Files.Core.Model
{
public class ChangeOwnerModel: BaseBatchModel<JsonElement>
{
public Guid UserId { get; set; }
}
}

View File

@ -1,10 +1,11 @@
using System.IO;

using Microsoft.AspNetCore.Http;
namespace ASC.Files.Core.Model
{
public class FileStreamModel
{
public Stream File { get; set; }
public IFormFile File { get; set; }
public bool Encrypted { get; set; }
public bool Forcesave { get; set; }
}

View File

@ -1,10 +1,11 @@
using System.Collections.Generic;
using System.Text.Json;
using ASC.Api.Documents;
namespace ASC.Files.Model
{
public class SecurityInfoModel
public class SecurityInfoModel : BaseBatchModel<JsonElement>
{
public IEnumerable<FileShareParams> Share { get; set; }
public bool Notify { get; set; }

View File

@ -266,7 +266,7 @@ namespace ASC.Web.Files.Services.DocumentService
try
{
return FileSharing.GetSharedInfoShort<string>(File.UniqID);
return FileSharing.GetSharedInfoShortFile(File.ID);
}
catch
{

View File

@ -56,7 +56,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
{
var operations = tasks.GetTasks();
var processlist = Process.GetProcesses();
//TODO: replace with distributed cache
foreach (var o in operations.Where(o => processlist.All(p => p.Id != o.InstanceId)))
{
o.SetProperty(FileOperation.PROGRESS, 100);

View File

@ -172,7 +172,7 @@ namespace ASC.Web.Files.Services.WCFService
ItemList<AceShortWrapper> GetSharedInfoShort(string objectId);
ItemList<string> SetAceObject(AceCollection aceCollection, bool notify);
List<T> SetAceObject(AceCollection<T> aceCollection, bool notify);
void RemoveAce(ItemList<string> items);

View File

@ -25,6 +25,7 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ASC.Files.Core;
@ -33,9 +34,10 @@ using ASC.Files.Core.Security;
namespace ASC.Web.Files.Services.WCFService
{
public class AceCollection
public class AceCollection<T>
{
public ItemList<string> Entries { get; set; }
public IEnumerable<T> Files { get; set; }
public IEnumerable<T> Folders { get; set; }
public ItemList<AceWrapper> Aces { get; set; }

View File

@ -424,7 +424,7 @@ namespace ASC.Web.Files.Utils
return result;
}
public ItemList<AceWrapper> GetSharedInfo<T>(ItemList<string> objectIds)
public ItemList<AceWrapper> GetSharedInfo<T>(IEnumerable<T> fileIds, IEnumerable<T> folderIds)
{
if (!AuthContext.IsAuthenticated)
{
@ -433,23 +433,16 @@ namespace ASC.Web.Files.Utils
var result = new List<AceWrapper>();
var folderDao = DaoFactory.GetFolderDao<T>();
var fileDao = DaoFactory.GetFileDao<T>();
var fileDao = DaoFactory.GetFileDao<T>();
var files = fileDao.GetFiles(fileIds);
var folderDao = DaoFactory.GetFolderDao<T>();
var folders = folderDao.GetFolders(folderIds);
var entries = files.Cast<FileEntry<T>>().Concat(folders.Cast<FileEntry<T>>());
foreach (var objectId in objectIds)
foreach (var entry in entries)
{
if (string.IsNullOrEmpty(objectId))
{
throw new InvalidOperationException(FilesCommonResource.ErrorMassage_BadRequest);
}
var entryType = objectId.StartsWith("file_") ? FileEntryType.File : FileEntryType.Folder;
var entryId = (T)Convert.ChangeType(objectId.Substring((entryType == FileEntryType.File ? "file_" : "folder_").Length), typeof(T));
var entry = entryType == FileEntryType.File
? fileDao.GetFile(entryId)
: (FileEntry<T>)folderDao.GetFolder(entryId);
IEnumerable<AceWrapper> acesForObject;
try
{
@ -516,7 +509,7 @@ namespace ASC.Web.Files.Utils
result.Remove(meAce);
AceWrapper linkAce = null;
if (objectIds.Count > 1)
if (entries.Any())
{
result.RemoveAll(ace => ace.SubjectId == FileConstant.ShareLinkId);
}
@ -544,13 +537,25 @@ namespace ASC.Web.Files.Utils
return new ItemList<AceWrapper>(result);
}
public ItemList<AceShortWrapper> GetSharedInfoShort<T>(string objectId)
public ItemList<AceShortWrapper> GetSharedInfoShortFile<T>(T fileID)
{
var aces = GetSharedInfo<T>(new ItemList<string> { objectId });
var aces = GetSharedInfo(new List<T> { fileID}, new List<T>());
return GetAceShortWrappers(aces);
}
return new ItemList<AceShortWrapper>(
aces.Where(aceWrapper => !aceWrapper.SubjectId.Equals(FileConstant.ShareLinkId) || aceWrapper.Share != FileShare.Restrict)
.Select(aceWrapper => new AceShortWrapper(aceWrapper)));
public ItemList<AceShortWrapper> GetSharedInfoShortFolder<T>(T folderId)
{
var aces = GetSharedInfo(new List<T>(), new List<T> { folderId });
return GetAceShortWrappers(aces);
}
private ItemList<AceShortWrapper> GetAceShortWrappers(ItemList<AceWrapper> aces)
{
return new ItemList<AceShortWrapper>(aces
.Where(aceWrapper => !aceWrapper.SubjectId.Equals(FileConstant.ShareLinkId) || aceWrapper.Share != FileShare.Restrict)
.Select(aceWrapper => new AceShortWrapper(aceWrapper)));
}
}
}

View File

@ -97,8 +97,8 @@ namespace ASC.Api.Documents
private WordpressHelper WordpressHelper { get; }
private EasyBibHelper EasyBibHelper { get; }
private ProductEntryPoint ProductEntryPoint { get; }
public TenantManager TenantManager { get; }
public FileUtility FileUtility { get; }
private TenantManager TenantManager { get; }
private FileUtility FileUtility { get; }
/// <summary>
/// </summary>
@ -596,30 +596,17 @@ namespace ASC.Api.Documents
/// <param name="encrypted"></param>
/// <returns></returns>
/// <visible>false</visible>
[Update("{fileId}/update", DisableFormat = true)]
public FileWrapper<string> UpdateFileStreamFromBody(string fileId, [FromBody]FileStreamModel model)
{
return FilesControllerHelperString.UpdateFileStream(model.File, fileId, model.Encrypted, model.Forcesave);
}
[Update("{fileId}/update", DisableFormat = true)]
[Consumes("application/x-www-form-urlencoded")]
public FileWrapper<string> UpdateFileStreamFromForm(string fileId, [FromForm]FileStreamModel model)
{
return FilesControllerHelperString.UpdateFileStream(model.File, fileId, model.Encrypted, model.Forcesave);
return FilesControllerHelperString.UpdateFileStream(model.File.OpenReadStream(), fileId, model.Encrypted, model.Forcesave);
}
[Update("{fileId:int}/update")]
public FileWrapper<int> UpdateFileStreamFromBody(int fileId, [FromBody]FileStreamModel model)
{
return FilesControllerHelperInt.UpdateFileStream(model.File, fileId, model.Encrypted, model.Forcesave);
}
[Update("{fileId:int}/update")]
[Consumes("application/x-www-form-urlencoded")]
public FileWrapper<int> UpdateFileStreamFromForm(int fileId, [FromForm]FileStreamModel model)
{
return FilesControllerHelperInt.UpdateFileStream(model.File, fileId, model.Encrypted, model.Forcesave);
return FilesControllerHelperInt.UpdateFileStream(model.File.OpenReadStream(), fileId, model.Encrypted, model.Forcesave);
}
@ -1098,6 +1085,27 @@ namespace ASC.Api.Documents
return FilesControllerHelperInt.RenameFolder(folderId, folderModel.Title);
}
[Create("owner")]
public IEnumerable<FileEntryWrapper> ChangeOwnerFromBody([FromBody] ChangeOwnerModel model)
{
return ChangeOwner(model);
}
[Create("owner")]
[Consumes("application/x-www-form-urlencoded")]
public IEnumerable<FileEntryWrapper> ChangeOwnerFromForm([FromForm] ChangeOwnerModel model)
{
return ChangeOwner(model);
}
public IEnumerable<FileEntryWrapper> ChangeOwner(ChangeOwnerModel model)
{
var result = new List<FileEntry>();
result.AddRange(FileStorageServiceInt.ChangeOwner(model.FolderIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()).ToList(), model.FileIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()).ToList(), model.UserId));
result.AddRange(FileStorageService.ChangeOwner(model.FolderIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()).ToList(), model.FileIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()).ToList(), model.UserId));
return result.Select(FilesControllerHelperInt.GetFileEntryWrapper);
}
/// <summary>
/// Returns a detailed information about the folder with the ID specified in the request
/// </summary>
@ -1583,6 +1591,25 @@ namespace ASC.Api.Documents
return FilesControllerHelperInt.GetFolderSecurityInfo(folderId);
}
[Create("share")]
public IEnumerable<FileShareWrapper> GetSecurityInfoFromBody([FromBody] BaseBatchModel<JsonElement> model)
{
var result = new List<FileShareWrapper>();
result.AddRange(FilesControllerHelperInt.GetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32())));
result.AddRange(FilesControllerHelperString.GetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString())));
return result;
}
[Create("share")]
[Consumes("application/x-www-form-urlencoded")]
public IEnumerable<FileShareWrapper> GetSecurityInfoFromForm([FromForm] BaseBatchModel<JsonElement> model)
{
var result = new List<FileShareWrapper>();
result.AddRange(FilesControllerHelperInt.GetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32())));
result.AddRange(FilesControllerHelperString.GetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString())));
return result;
}
/// <summary>
/// Sets sharing settings for the file with the ID specified in the request
/// </summary>
@ -1622,6 +1649,27 @@ namespace ASC.Api.Documents
return FilesControllerHelperInt.SetFileSecurityInfo(fileId, model.Share, model.Notify, model.SharingMessage);
}
[Update("share")]
public IEnumerable<FileShareWrapper> SetSecurityInfoFromBody([FromBody]SecurityInfoModel model)
{
return SetSecurityInfo(model);
}
[Update("share")]
[Consumes("application/x-www-form-urlencoded")]
public IEnumerable<FileShareWrapper> SetSecurityInfoFromForm([FromForm]SecurityInfoModel model)
{
return SetSecurityInfo(model);
}
public IEnumerable<FileShareWrapper> SetSecurityInfo(SecurityInfoModel model)
{
var result = new List<FileShareWrapper>();
result.AddRange(FilesControllerHelperInt.SetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()).ToList(), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.Number).Select(r => r.GetInt32()).ToList(), model.Share, model.Notify, model.SharingMessage));
result.AddRange(FilesControllerHelperString.SetSecurityInfo(model.FileIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()).ToList(), model.FolderIds.Where(r => r.ValueKind == JsonValueKind.String).Select(r => r.GetString()).ToList(), model.Share, model.Notify, model.SharingMessage));
return result;
}
/// <summary>
/// Sets sharing settings for the folder with the ID specified in the request
/// </summary>

View File

@ -293,16 +293,7 @@ namespace ASC.Files.Helpers
public IEnumerable<FileEntryWrapper> GetFolderPath(T folderId)
{
return EntryManager.GetBreadCrumbs(folderId).Select(r =>
{
if (r is Folder<string> f1)
return FolderWrapperHelper.Get(f1);
if (r is Folder<int> f2)
return FolderWrapperHelper.Get(f2);
return default(FileEntryWrapper);
});
return EntryManager.GetBreadCrumbs(folderId).Select(GetFileEntryWrapper);
}
public FileWrapper<T> GetFileInfo(T fileId, int version = -1)
@ -321,28 +312,7 @@ namespace ASC.Files.Helpers
public List<FileEntryWrapper> GetNewItems(T folderId)
{
return FileStorageService.GetNewItems(folderId)
.Select(r =>
{
FileEntryWrapper wrapper = null;
if (r is Folder<int> fol1)
{
wrapper = FolderWrapperHelper.Get(fol1);
}
else if (r is Folder<string> fol2)
{
wrapper = FolderWrapperHelper.Get(fol2);
}
else if (r is File<int> file1)
{
wrapper = FileWrapperHelper.Get(file1);
}
else if (r is File<string> file2)
{
wrapper = FileWrapperHelper.Get(file2);
}
return wrapper;
})
.Select(GetFileEntryWrapper)
.ToList();
}
@ -415,20 +385,7 @@ namespace ASC.Files.Helpers
entries.AddRange(FileStorageService.GetItems(checkedFiles.OfType<string>(), checkedFiles.OfType<string>(), FilterType.FilesOnly, false, "", ""));
return entries.Select(r =>
{
FileEntryWrapper wrapper = null;
if (r is Folder<int> fol1)
{
wrapper = FolderWrapperHelper.Get(fol1);
}
if (r is Folder<string> fol2)
{
wrapper = FolderWrapperHelper.Get(fol2);
}
return wrapper;
});
return entries.Select(GetFileEntryWrapper);
}
public IEnumerable<FileOperationWraper> MoveBatchItems(BatchModel batchModel)
@ -511,47 +468,46 @@ namespace ASC.Files.Helpers
public IEnumerable<FileShareWrapper> GetFileSecurityInfo(T fileId)
{
var fileShares = FileStorageService.GetSharedInfo(new ItemList<string> { string.Format("file_{0}", fileId) });
return fileShares.Select(FileShareWrapperHelper.Get);
return GetSecurityInfo(new List<T> { fileId }, new List<T> { });
}
public IEnumerable<FileShareWrapper> GetFolderSecurityInfo(T folderId)
{
var fileShares = FileStorageService.GetSharedInfo(new ItemList<string> { string.Format("folder_{0}", folderId) });
return GetSecurityInfo(new List<T> { }, new List<T> { folderId });
}
public IEnumerable<FileShareWrapper> GetSecurityInfo(IEnumerable<T> fileIds, IEnumerable<T> folderIds)
{
var fileShares = FileStorageService.GetSharedInfo(fileIds, folderIds);
return fileShares.Select(FileShareWrapperHelper.Get);
}
public IEnumerable<FileShareWrapper> SetFileSecurityInfo(T fileId, IEnumerable<FileShareParams> share, bool notify, string sharingMessage)
{
if (share != null && share.Any())
{
var list = new ItemList<AceWrapper>(share.Select(FileShareParamsHelper.ToAceObject));
var aceCollection = new AceCollection
{
Entries = new ItemList<string> { "file_" + fileId },
Aces = list,
Message = sharingMessage
};
FileStorageService.SetAceObject(aceCollection, notify);
}
return GetFileSecurityInfo(fileId);
return SetSecurityInfo(new List<T> { fileId }, new List<T>(), share, notify, sharingMessage);
}
public IEnumerable<FileShareWrapper> SetFolderSecurityInfo(T folderId, IEnumerable<FileShareParams> share, bool notify, string sharingMessage)
{
return SetSecurityInfo(new List<T>(), new List<T> { folderId}, share, notify, sharingMessage);
}
public IEnumerable<FileShareWrapper> SetSecurityInfo(IEnumerable<T> fileIds, IEnumerable<T> folderIds, IEnumerable<FileShareParams> share, bool notify, string sharingMessage)
{
if (share != null && share.Any())
{
var list = new ItemList<AceWrapper>(share.Select(FileShareParamsHelper.ToAceObject));
var aceCollection = new AceCollection
var aceCollection = new AceCollection<T>
{
Entries = new ItemList<string> { "folder_" + folderId },
Files = fileIds,
Folders = folderIds,
Aces = list,
Message = sharingMessage
};
FileStorageService.SetAceObject(aceCollection, notify);
}
return GetFolderSecurityInfo(folderId);
return GetSecurityInfo(fileIds, folderIds);
}
public bool RemoveSecurityInfo(List<T> fileIds, List<T> folderIds)
@ -565,8 +521,7 @@ namespace ASC.Files.Helpers
{
var file = GetFileInfo(fileId);
var objectId = "file_" + file.Id;
var sharedInfo = FileStorageService.GetSharedInfo(new ItemList<string> { objectId }).Find(r => r.SubjectId == FileConstant.ShareLinkId);
var sharedInfo = FileStorageService.GetSharedInfo(new List<T> { fileId }, new List<T> { }).Find(r => r.SubjectId == FileConstant.ShareLinkId);
if (sharedInfo == null || sharedInfo.Share != share)
{
var list = new ItemList<AceWrapper>
@ -578,13 +533,13 @@ namespace ASC.Files.Helpers
Share = share
}
};
var aceCollection = new AceCollection
var aceCollection = new AceCollection<T>
{
Entries = new ItemList<string> { objectId },
Files = new List<T> { fileId },
Aces = list
};
FileStorageService.SetAceObject(aceCollection, false);
sharedInfo = FileStorageService.GetSharedInfo(new ItemList<string> { objectId }).Find(r => r.SubjectId == FileConstant.ShareLinkId);
sharedInfo = FileStorageService.GetSharedInfo(new List<T> { fileId }, new List<T> { }).Find(r => r.SubjectId == FileConstant.ShareLinkId);
}
return sharedInfo.Link;
@ -626,5 +581,28 @@ namespace ASC.Files.Helpers
new OrderBy(sortBy, !ApiContext.SortDescending)),
startIndex);
}
internal FileEntryWrapper GetFileEntryWrapper(FileEntry r)
{
FileEntryWrapper wrapper = null;
if (r is Folder<int> fol1)
{
wrapper = FolderWrapperHelper.Get(fol1);
}
else if (r is Folder<string> fol2)
{
wrapper = FolderWrapperHelper.Get(fol2);
}
else if (r is File<int> file1)
{
wrapper = FileWrapperHelper.Get(file1);
}
else if (r is File<string> file2)
{
wrapper = FileWrapperHelper.Get(file2);
}
return wrapper;
}
}
}

View File

@ -392,7 +392,10 @@ class SectionBodyContent extends React.PureComponent {
<>
<Consumer>
{(context) => (
<RowContainer className="people-row" useReactWindow={false}>
<RowContainer
className="people-row-container"
useReactWindow={false}
>
{peopleList.map((man) => {
const {
checked,

View File

@ -26,6 +26,11 @@ const commonStyles = css`
flex-direction: column;
min-height: 100%;
}
.people-row-container,
.files-row-container {
margin-top: -22px;
}
}
`;

View File

@ -15,7 +15,6 @@ const StyledRowContainer = styled.div`
: "100%"
: "auto"};
position: relative;
margin-top:-18px;
`;
class RowContainer extends React.PureComponent {