diff --git a/common/ASC.Core.Common/Notify/Signalr/SocketServiceClient.cs b/common/ASC.Core.Common/Notify/Signalr/SocketServiceClient.cs index 05d7ca21f8c..017d98fb8eb 100644 --- a/common/ASC.Core.Common/Notify/Signalr/SocketServiceClient.cs +++ b/common/ASC.Core.Common/Notify/Signalr/SocketServiceClient.cs @@ -38,37 +38,37 @@ public class SocketServiceClient private readonly byte[] _sKey; private readonly string _url; - public virtual string Hub { get => "default"; } + private static readonly JsonSerializerOptions _options = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + protected virtual string Hub { get => "default"; } public SocketServiceClient( ILogger logger, IHttpClientFactory clientFactory, - MachinePseudoKeys mashinePseudoKeys, + MachinePseudoKeys machinePseudoKeys, IConfiguration configuration) { _logger = logger; _clientFactory = clientFactory; - _sKey = mashinePseudoKeys.GetMachineConstant(); + _sKey = machinePseudoKeys.GetMachineConstant(); _url = configuration["web:hub:internal"]; _enableSocket = !string.IsNullOrEmpty(_url); } - public async Task MakeRequest(string method, object data) + public async Task MakeRequest(string method, object data) { if (!IsAvailable()) { - return string.Empty; + return; } try { var request = GenerateRequest(method, data); var httpClient = _clientFactory.CreateClient(); - - //async - using var response = await httpClient.SendAsync(request); - await using var stream = await response.Content.ReadAsStreamAsync(); - using var streamReader = new StreamReader(stream); - return await streamReader.ReadToEndAsync(); + await httpClient.SendAsync(request); } catch (Exception e) { @@ -79,15 +79,6 @@ public async Task MakeRequest(string method, object data) _lastErrorTime = DateTime.Now; } } - - return null; - } - - public async Task MakeRequest(string method, object data) - { - var resultMakeRequest = await MakeRequest(method, data); - - return JsonConvert.DeserializeObject(resultMakeRequest); } protected void SendNotAwaitableRequest(string method, object data) @@ -110,7 +101,7 @@ private HttpRequestMessage GenerateRequest(string method, object data) request.Method = HttpMethod.Post; request.RequestUri = new Uri(GetMethod(method)); - var jsonData = JsonConvert.SerializeObject(data); + var jsonData = JsonSerializer.Serialize(data, _options); _logger.DebugMakeRequest(method, jsonData); request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json"); diff --git a/common/ASC.Core.Common/Quota/QuotaSocketManager.cs b/common/ASC.Core.Common/Quota/QuotaSocketManager.cs index 4d38c44e1a6..5db504b4563 100644 --- a/common/ASC.Core.Common/Quota/QuotaSocketManager.cs +++ b/common/ASC.Core.Common/Quota/QuotaSocketManager.cs @@ -29,14 +29,14 @@ public class QuotaSocketManager : SocketServiceClient { private readonly TenantManager _tenantManager; - public override string Hub => "files"; + protected override string Hub => "files"; public QuotaSocketManager( ILogger logger, IHttpClientFactory clientFactory, - MachinePseudoKeys mashinePseudoKeys, + MachinePseudoKeys machinePseudoKeys, TenantManager tenantManager, - IConfiguration configuration) : base(logger, clientFactory, mashinePseudoKeys, configuration) + IConfiguration configuration) : base(logger, clientFactory, machinePseudoKeys, configuration) { _tenantManager = tenantManager; } diff --git a/common/ASC.Socket.IO/app/controllers/files.js b/common/ASC.Socket.IO/app/controllers/files.js index 38a3fa4ccb0..ccbb0fa0a56 100644 --- a/common/ASC.Socket.IO/app/controllers/files.js +++ b/common/ASC.Socket.IO/app/controllers/files.js @@ -41,12 +41,12 @@ res.end(); }); - router.post("/markasnew-file", (req, res) => { + router.post("/mark-as-new-file", (req, res) => { files.markAsNewFiles(req.body); res.end(); }); - router.post("/markasnew-folder", (req, res) => { + router.post("/mark-as-new-folder", (req, res) => { files.markAsNewFolders(req.body); res.end(); }); diff --git a/common/ASC.Socket.IO/app/hubs/files.js b/common/ASC.Socket.IO/app/hubs/files.js index bcc0aaf4025..82886d76f8e 100644 --- a/common/ASC.Socket.IO/app/hubs/files.js +++ b/common/ASC.Socket.IO/app/hubs/files.js @@ -1,4 +1,5 @@ -module.exports = (io) => { +const logger = require("../log"); +module.exports = (io) => { const logger = require("../log.js"); const moment = require("moment"); const filesIO = io; //TODO: Restore .of("/files"); @@ -141,42 +142,82 @@ filesIO.to(room).emit("s:modify-folder", { cmd, id, type, data }); } - function createFile({ fileId, room, data } = {}) { - logger.info(`create new file ${fileId} in room ${room}`); - modifyFolder(room, "create", fileId, "file", data); + function createFile({ id, room, data, userIds } = {}) { + logger.info(`create new file ${id} in room ${room}`); + + if(userIds) + { + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "create", id, "file", data)); + } + else + { + modifyFolder(room, "create", id, "file", data); + } } - function createFolder({ folderId, room, data, userIds } = {}) { - logger.info(`create new folder ${folderId} in room ${room}`); - logger.info(`create new folder length ${userIds.length}`); + function createFolder({ id, room, data, userIds } = {}) { + logger.info(`create new folder ${id} in room ${room}`); if(userIds) { - userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "create", folderId, "folder", data)); + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "create", id, "folder", data)); } else { - modifyFolder(room, "create", folderId, "folder", data); + modifyFolder(room, "create", id, "folder", data); } } - function updateFile({ fileId, room, data } = {}) { - logger.info(`update file ${fileId} in room ${room}`); - modifyFolder(room, "update", fileId, "file", data); + function updateFile({ id, room, data, userIds } = {}) { + logger.info(`update file ${id} in room ${room}`); + + if(userIds) + { + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "update", id, "file", data)); + } + else + { + modifyFolder(room, "update", id, "file", data); + } } - function updateFolder({ folderId, room, data } = {}) { - logger.info(`update folder ${folderId} in room ${room}`); - modifyFolder(room, "update", folderId, "folder", data); + function updateFolder({ id, room, data, userIds } = {}) { + logger.info(`update folder ${id} in room ${room}`); + modifyFolder(room, "update", id, "folder", data); + + if(userIds) + { + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "update", id, "folder", data)); + } + else + { + modifyFolder(room, "update", id, "folder", data); + } } - function deleteFile({ fileId, room } = {}) { - logger.info(`delete file ${fileId} in room ${room}`); - modifyFolder(room, "delete", fileId, "file"); + function deleteFile({ id, room, userIds } = {}) { + logger.info(`delete file ${id} in room ${room}`); + + if(userIds) + { + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "delete", id, "file")); + } + else + { + modifyFolder(room, "delete", id, "file"); + } } - function deleteFolder({ folderId, room } = {}) { - logger.info(`delete file ${folderId} in room ${room}`); - modifyFolder(room, "delete", folderId, "folder"); + function deleteFolder({ id, room, userIds } = {}) { + logger.info(`delete folder ${id} in room ${room}`); + + if(userIds) + { + userIds.forEach(userId => modifyFolder(`${room}-${userId}`, "delete", id, "folder")); + } + else + { + modifyFolder(room, "delete", id, "folder"); + } } function markAsNewFile({ fileId, count, room } = {}) { diff --git a/products/ASC.Files/Core/Services/WCFService/FileOperations/FileMoveCopyOperation.cs b/products/ASC.Files/Core/Services/WCFService/FileOperations/FileMoveCopyOperation.cs index 0e49156c2de..eae4f49010e 100644 --- a/products/ASC.Files/Core/Services/WCFService/FileOperations/FileMoveCopyOperation.cs +++ b/products/ASC.Files/Core/Services/WCFService/FileOperations/FileMoveCopyOperation.cs @@ -116,7 +116,6 @@ private async Task DoAsync(IServiceScope scope, TTo tto) var folderDao = scope.ServiceProvider.GetService>(); var fileSecurity = scope.ServiceProvider.GetService(); var socketManager = scope.ServiceProvider.GetService(); - var userManager = scope.ServiceProvider.GetService(); //TODO: check on each iteration? var toFolder = await folderDao.GetFolderAsync(tto); @@ -212,18 +211,13 @@ private async Task DoAsync(IServiceScope scope, TTo tto) needToMark.AddRange(moveOrCopyFilesTask); - var admins = await userManager.GetUsers(true, EmployeeStatus.Active, null, null, null, null, null, null, null, true, 0, 0).Select(r=> r.Id).ToListAsync(); - admins.Add(CurrentTenant.OwnerId); - foreach (var folder in moveOrCopyFoldersTask) { if (toFolder.FolderType != FolderType.Archive && !DocSpaceHelper.IsRoom(folder.FolderType)) { needToMark.AddRange(await GetFilesAsync(scope, folder)); } - - var whoCanRead = await fileSecurity.WhoCanReadAsync(folder); - await socketManager.CreateFolderAsync(folder, admins.Concat(whoCanRead).Distinct().ToList()); + await socketManager.CreateFolderAsync(folder); } var ntm = needToMark.Distinct(); diff --git a/products/ASC.Files/Core/Utils/SocketManager.cs b/products/ASC.Files/Core/Utils/SocketManager.cs index 5312f63b83a..3d20034844f 100644 --- a/products/ASC.Files/Core/Utils/SocketManager.cs +++ b/products/ASC.Files/Core/Utils/SocketManager.cs @@ -30,22 +30,28 @@ public class SocketManager : SocketServiceClient { private readonly FileDtoHelper _filesWrapperHelper; private readonly FolderDtoHelper _folderDtoHelper; + private readonly FileSecurity _fileSecurity; + private readonly UserManager _userManager; private readonly TenantManager _tenantManager; - public override string Hub => "files"; + protected override string Hub => "files"; public SocketManager( ILogger logger, IHttpClientFactory clientFactory, - MachinePseudoKeys mashinePseudoKeys, + MachinePseudoKeys machinePseudoKeys, IConfiguration configuration, FileDtoHelper filesWrapperHelper, TenantManager tenantManager, - FolderDtoHelper folderDtoHelper) : base(logger, clientFactory, mashinePseudoKeys, configuration) + FolderDtoHelper folderDtoHelper, + FileSecurity fileSecurity, + UserManager userManager) : base(logger, clientFactory, machinePseudoKeys, configuration) { _filesWrapperHelper = filesWrapperHelper; _tenantManager = tenantManager; _folderDtoHelper = folderDtoHelper; + _fileSecurity = fileSecurity; + _userManager = userManager; } public async Task StartEditAsync(T fileId) @@ -61,78 +67,33 @@ public async Task StopEditAsync(T fileId) } public async Task CreateFileAsync(File file) - { - var room = await GetFolderRoomAsync(file.ParentId); - - var data = await SerializeFile(file); - - await MakeRequest("create-file", new { room, fileId = file.Id, data }); + { + await MakeRequest("create-file", file, true); } - public async Task CreateFolderAsync(Folder folder, IEnumerable userIds = null) - { - var room = await GetFolderRoomAsync(folder.ParentId); - - var data = await SerializeFolder(folder); - - if (userIds != null && userIds.Any()) - { - foreach (var chunk in userIds.Chunk(1000)) - { - await MakeRequest("create-folder", - new - { - room, - folderId = folder.Id, - data, - userIds = chunk - }); - } - - } - else - { - await MakeRequest("create-folder", - new - { - room, - folderId = folder.Id, - data - }); - } - + public async Task CreateFolderAsync(Folder folder) + { + await MakeRequest("create-folder", folder, true); } public async Task UpdateFileAsync(File file) - { - var room = await GetFolderRoomAsync(file.ParentId); - - var data = await SerializeFile(file); - - await MakeRequest("update-file", new { room, fileId = file.Id, data }); + { + await MakeRequest("update-file", file, true); } public async Task UpdateFolderAsync(Folder folder) - { - var room = await GetFolderRoomAsync(folder.ParentId); - - var data = await SerializeFolder(folder); - - await MakeRequest("update-folder", new { room, folderId = folder.Id, data }); + { + await MakeRequest("update-folder", folder, true); } public async Task DeleteFileAsync(File file) - { - var room = await GetFolderRoomAsync(file.ParentId); - - await MakeRequest("delete-file", new { room, fileId = file.Id }); + { + await MakeRequest("delete-file", file); } public async Task DeleteFolder(Folder folder) { - var room = await GetFolderRoomAsync(folder.ParentId); - - await MakeRequest("delete-folder", new { room, folderId = folder.Id }); + await MakeRequest("delete-folder", folder); } public async Task ExecMarkAsNewFilesAsync(IEnumerable tags) @@ -145,7 +106,7 @@ public async Task ExecMarkAsNewFilesAsync(IEnumerable tags) result.Add(new { room, fileId = g.Key }); } - SendNotAwaitableRequest("markasnew-file", result); + SendNotAwaitableRequest("mark-as-new-file", result); } public async Task ExecMarkAsNewFoldersAsync(IEnumerable tags) @@ -159,11 +120,34 @@ public async Task ExecMarkAsNewFoldersAsync(IEnumerable tags) new { room, folderId = g.Key, - userIds = g.Select(r=> new { owner = r.Owner, count = r.Count}).ToList() + userIds = g.Select(r => new { owner = r.Owner, count = r.Count}).ToList() }); } - SendNotAwaitableRequest("markasnew-folder", result); + SendNotAwaitableRequest("mark-as-new-folder", result); + } + + private async Task MakeRequest(string method, FileEntry entry, bool withData = false) + { + var room = await GetFolderRoomAsync(entry.ParentId); + var whoCanRead = await GetWhoCanRead(entry); + var data = ""; + + if (withData) + { + data = await Serialize(entry); + } + + foreach (var userIds in whoCanRead.Chunk(1000)) + { + await base.MakeRequest(method, new + { + room, + entry.Id, + data, + userIds, + }); + } } private async Task GetFileRoomAsync(T fileId) @@ -180,13 +164,41 @@ private async Task GetFolderRoomAsync(T folderId) return $"{tenantId}-DIR-{folderId}"; } - private async Task SerializeFile(File file) + private async Task Serialize(FileEntry entry) { - return JsonSerializer.Serialize(await _filesWrapperHelper.GetAsync(file), typeof(FileDto), FileEntryDtoContext.Default); + return entry switch + { + File file => JsonSerializer.Serialize(await _filesWrapperHelper.GetAsync(file), typeof(FileDto), FileEntryDtoContext.Default), + Folder folder => JsonSerializer.Serialize(await _folderDtoHelper.GetAsync(folder), typeof(FolderDto), FileEntryDtoContext.Default), + _ => string.Empty + }; } - private async Task SerializeFolder(Folder folder) + private List _admins; + private async Task> GetAdmins() + { + if (_admins != null) + { + return _admins; + } + + _admins = await _userManager.GetUsers(true, EmployeeStatus.Active, null, null, null, null, null, null, null, true, 0, 0) + .Select(r=> r.Id) + .ToListAsync(); + + _admins.Add((await _tenantManager.GetCurrentTenantAsync()).OwnerId); + + return _admins; + } + + private async Task> GetWhoCanRead(FileEntry entry) { - return JsonSerializer.Serialize(await _folderDtoHelper.GetAsync(folder), typeof(FolderDto), FileEntryDtoContext.Default); + var whoCanRead = await _fileSecurity.WhoCanReadAsync(entry); + var userIds = whoCanRead + .Concat(await GetAdmins()) + .Distinct() + .ToList(); + + return userIds; } }