diff --git a/build/build.document.server.docker.bat b/build/build.document.server.docker.bat new file mode 100644 index 0000000000..2af3d4fa50 --- /dev/null +++ b/build/build.document.server.docker.bat @@ -0,0 +1,7 @@ +@echo off + +pwsh %~dp0/build.document.server.docker.ps1 %1 + +echo. + +pause \ No newline at end of file diff --git a/build/build.document.server.docker.ps1 b/build/build.document.server.docker.ps1 new file mode 100644 index 0000000000..64de00bbf6 --- /dev/null +++ b/build/build.document.server.docker.ps1 @@ -0,0 +1,15 @@ +$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object { $_.major } +$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object { $_.minor } + +if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) { + Write-Error "Powershell version must be greater than or equal to 7.2." + exit +} + +$RootDir = Split-Path -Parent $PSScriptRoot + +Write-Host "Run Document server" -ForegroundColor Green +$DOCUMENT_SERVER_IMAGE_NAME = "onlyoffice/documentserver-de:latest" + + +docker run -i -t -d -p 8085:80 -e JWT_ENABLED=false -e JWT_IN_BODY=false --restart=always -v $RootDir/Data:/var/www/onlyoffice/Data $DOCUMENT_SERVER_IMAGE_NAME \ No newline at end of file diff --git a/common/ASC.Core.Common/Context/SecurityContext.cs b/common/ASC.Core.Common/Context/SecurityContext.cs index 209ce050ca..70476df0fe 100644 --- a/common/ASC.Core.Common/Context/SecurityContext.cs +++ b/common/ASC.Core.Common/Context/SecurityContext.cs @@ -161,8 +161,9 @@ public class SecurityContext return false; } - var settingLoginEvents = await _dbLoginEventsManager.GetLoginEventIds(tenant, userid); - if (loginEventId != 0 && !settingLoginEvents.Contains(loginEventId)) + var loginEventById = await _dbLoginEventsManager.GetById(loginEventId); + + if (loginEventById == null) { return false; } diff --git a/common/ASC.Core.Common/Core/Payments.cs b/common/ASC.Core.Common/Core/Payments.cs new file mode 100644 index 0000000000..7133a734e8 --- /dev/null +++ b/common/ASC.Core.Common/Core/Payments.cs @@ -0,0 +1,32 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL 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 details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Core; +public enum Payments +{ + Paid = 0, + Free = 1 +} \ No newline at end of file diff --git a/common/ASC.Core.Common/Data/DbLoginEventsManager.cs b/common/ASC.Core.Common/Data/DbLoginEventsManager.cs index 0553efd5e4..a43971ba07 100644 --- a/common/ASC.Core.Common/Data/DbLoginEventsManager.cs +++ b/common/ASC.Core.Common/Data/DbLoginEventsManager.cs @@ -24,6 +24,8 @@ // content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode +using System.ComponentModel; + namespace ASC.Core.Data; [Scope] @@ -61,26 +63,22 @@ public class DbLoginEventsManager _dbContextFactory = dbContextFactory; _mapper = mapper; } - - public async Task> GetLoginEventIds(int tenantId, Guid userId) + + public async Task GetById(int id) { - var date = DateTime.UtcNow.AddYears(-1); + if (id < 0) return null; - using var loginEventContext = _dbContextFactory.CreateDbContext(); - - var resultList = await loginEventContext.LoginEvents - .Where(r => r.TenantId == tenantId && r.UserId == userId && _loginActions.Contains(r.Action ?? 0) && r.Date >= date && r.Active) - .Select(r => r.Id) - .ToListAsync(); - - return resultList; - } + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + + return await loginEventContext.LoginEvents.FindAsync(id); + } public async Task> GetLoginEvents(int tenantId, Guid userId) { var date = DateTime.UtcNow.AddYears(-1); - using var loginEventContext = _dbContextFactory.CreateDbContext(); + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + var loginInfo = await loginEventContext.LoginEvents .Where(r => r.TenantId == tenantId && r.UserId == userId && _loginActions.Contains(r.Action ?? 0) && r.Date >= date && r.Active) .OrderByDescending(r => r.Id) @@ -91,7 +89,8 @@ public class DbLoginEventsManager public async Task LogOutEvent(int loginEventId) { - using var loginEventContext = _dbContextFactory.CreateDbContext(); + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + var events = await loginEventContext.LoginEvents .Where(r => r.Id == loginEventId) .ToListAsync(); @@ -108,7 +107,8 @@ public class DbLoginEventsManager public async Task LogOutAllActiveConnections(int tenantId, Guid userId) { - using var loginEventContext = _dbContextFactory.CreateDbContext(); + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + var events = await loginEventContext.LoginEvents .Where(r => r.TenantId == tenantId && r.UserId == userId && r.Active) .ToListAsync(); @@ -125,7 +125,8 @@ public class DbLoginEventsManager public async Task LogOutAllActiveConnectionsForTenant(int tenantId) { - using var loginEventContext = _dbContextFactory.CreateDbContext(); + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + var events = await loginEventContext.LoginEvents .Where(r => r.TenantId == tenantId && r.Active) .ToListAsync(); @@ -140,7 +141,8 @@ public class DbLoginEventsManager public async Task LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId) { - using var loginEventContext = _dbContextFactory.CreateDbContext(); + using var loginEventContext = await _dbContextFactory.CreateDbContextAsync(); + var events = await loginEventContext.LoginEvents .Where(r => r.TenantId == tenantId && r.UserId == userId && r.Id != loginEventId && r.Active) .ToListAsync(); diff --git a/common/ASC.Core.Common/Data/DbUserService.cs b/common/ASC.Core.Common/Data/DbUserService.cs index 5deef5ff7a..45362685d4 100644 --- a/common/ASC.Core.Common/Data/DbUserService.cs +++ b/common/ASC.Core.Common/Data/DbUserService.cs @@ -221,7 +221,18 @@ public class EFUserService : IUserService if (!string.IsNullOrEmpty(sortBy)) { - q = q.OrderBy(sortBy, sortOrderAsc); + if (sortBy == "type") + { + var q1 = from user in q join userGroup in userDbContext.UserGroups.Where(g => !g.Removed && (g.UserGroupId == Users.Constants.GroupAdmin.ID || g.UserGroupId == Users.Constants.GroupUser.ID)) + on user.Id equals userGroup.Userid into joinedGroup from @group in joinedGroup.DefaultIfEmpty() select new { user, @group }; + + q = sortOrderAsc ? q1.OrderBy(r => r.group != null && r.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : r.group == null ? 2 : 3).Select(r => r.user) + : q1.OrderByDescending(u => u.group != null && u.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : u.group == null ? 2 : 3).Select(r => r.user); + } + else + { + q = q.OrderBy(sortBy, sortOrderAsc); + } } if (offset != 0) diff --git a/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj index 1eac7b1f20..81af2639fb 100644 --- a/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj +++ b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj @@ -19,7 +19,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/config/appsettings.json b/config/appsettings.json index 793ba91918..0f4acdaffa 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -125,7 +125,7 @@ "ConnectionStrings": { "default": { "name": "default", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;Connection Timeout=30;Maximum Pool Size=300;ConnectionReset=false", "providerName": "MySql.Data.MySqlClient" }, "postgre": { @@ -135,7 +135,7 @@ }, "mysql": { "name": "mysql", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;Connection Timeout=30;Maximum Pool Size=300;ConnectionReset=false", "providerName": "MySql.Data.MySqlClient" } }, diff --git a/products/ASC.Files/Core/Core/Dao/Interfaces/IFolderDao.cs b/products/ASC.Files/Core/Core/Dao/Interfaces/IFolderDao.cs index 85af601d17..ddeb1ee83b 100644 --- a/products/ASC.Files/Core/Core/Dao/Interfaces/IFolderDao.cs +++ b/products/ASC.Files/Core/Core/Dao/Interfaces/IFolderDao.cs @@ -58,10 +58,10 @@ public interface IFolderDao Task> GetRootFolderByFileAsync(T fileId); IAsyncEnumerable> GetRoomsAsync(T parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, - bool withoutTags, bool excludeSubject, ProviderFilter provider); + bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds); IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, - bool withoutTags, bool excludeSubject, ProviderFilter provider); + bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds); /// /// Get a list of folders in current folder. diff --git a/products/ASC.Files/Core/Core/Dao/TeamlabDao/FolderDao.cs b/products/ASC.Files/Core/Core/Dao/TeamlabDao/FolderDao.cs index b064666277..faed44c7cc 100644 --- a/products/ASC.Files/Core/Core/Dao/TeamlabDao/FolderDao.cs +++ b/products/ASC.Files/Core/Core/Dao/TeamlabDao/FolderDao.cs @@ -164,7 +164,8 @@ internal class FolderDao : AbstractDao, IFolderDao return GetFoldersAsync(parentId, default, FilterType.None, false, default, string.Empty); } - public async IAsyncEnumerable> GetRoomsAsync(int parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public async IAsyncEnumerable> GetRoomsAsync(int parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, + IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || provider != ProviderFilter.None) { @@ -179,8 +180,8 @@ internal class FolderDao : AbstractDao, IFolderDao var filesDbContext = _dbContextFactory.CreateDbContext(); var q = GetFolderQuery(filesDbContext, r => r.ParentId == parentId).AsNoTracking(); - q = !withSubfolders ? BuildRoomsQuery(filesDbContext, q, filter, tags, subjectId, searchByTags, withoutTags, searchByTypes, false, excludeSubject) - : BuildRoomsWithSubfoldersQuery(filesDbContext, parentId, filter, tags, searchByTags, searchByTypes, withoutTags, excludeSubject, subjectId); + q = !withSubfolders ? BuildRoomsQuery(filesDbContext, q, filter, tags, subjectId, searchByTags, withoutTags, searchByTypes, false, excludeSubject, subjectFilter, subjectEntriesIds) + : BuildRoomsWithSubfoldersQuery(filesDbContext, parentId, filter, tags, searchByTags, searchByTypes, withoutTags, excludeSubject, subjectId, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -194,7 +195,7 @@ internal class FolderDao : AbstractDao, IFolderDao } } - public async IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public async IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || provider != ProviderFilter.None) { @@ -209,8 +210,8 @@ internal class FolderDao : AbstractDao, IFolderDao var filesDbContext = _dbContextFactory.CreateDbContext(); var q = GetFolderQuery(filesDbContext, f => roomsIds.Contains(f.Id) || (f.CreateBy == _authContext.CurrentAccount.ID && parentsIds.Contains(f.ParentId))).AsNoTracking(); - q = !withSubfolders ? BuildRoomsQuery(filesDbContext, q, filter, tags, subjectId, searchByTags, withoutTags, searchByTypes, false, excludeSubject) - : BuildRoomsWithSubfoldersQuery(filesDbContext, roomsIds, filter, tags, searchByTags, searchByTypes, withoutTags, excludeSubject, subjectId); + q = !withSubfolders ? BuildRoomsQuery(filesDbContext, q, filter, tags, subjectId, searchByTags, withoutTags, searchByTypes, false, excludeSubject, subjectFilter, subjectEntriesIds) + : BuildRoomsWithSubfoldersQuery(filesDbContext, roomsIds, filter, tags, searchByTags, searchByTypes, withoutTags, excludeSubject, subjectId, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -1458,8 +1459,21 @@ internal class FolderDao : AbstractDao, IFolderDao } private IQueryable BuildRoomsQuery(FilesDbContext filesDbContext, IQueryable query, FolderType filterByType, IEnumerable tags, Guid subjectId, bool searchByTags, bool withoutTags, - bool searchByFilter, bool withSubfolders, bool excludeSubject) + bool searchByFilter, bool withSubfolders, bool excludeSubject, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { + if (subjectId != Guid.Empty) + { + if (subjectFilter == SubjectFilter.Owner) + { + query = excludeSubject ? query.Where(f => f.CreateBy != subjectId) : query.Where(f => f.CreateBy == subjectId); + } + else if (subjectFilter == SubjectFilter.Member) + { + query = excludeSubject ? query.Where(f => f.CreateBy != subjectId && !subjectEntriesIds.Contains(f.Id.ToString())) + : query.Where(f => f.CreateBy == subjectId || subjectEntriesIds.Contains(f.Id.ToString())); + } + } + if (searchByFilter) { query = query.Where(f => f.FolderType == filterByType); @@ -1471,11 +1485,6 @@ internal class FolderDao : AbstractDao, IFolderDao .Where(r => r.tag.Type == TagType.Custom).Any(t => t.EntryId == f.Id.ToString())); } - if (subjectId != Guid.Empty) - { - query = excludeSubject ? query.Where(f => f.CreateBy != subjectId) : query.Where(f => f.CreateBy == subjectId); - } - if (searchByTags && !withSubfolders) { query = query.Join(filesDbContext.TagLink, f => f.Id.ToString(), t => t.EntryId, (folder, tag) => new { folder, tag.TagId }) @@ -1488,11 +1497,11 @@ internal class FolderDao : AbstractDao, IFolderDao } private IQueryable BuildRoomsWithSubfoldersQuery(FilesDbContext filesDbContext, int parentId, FolderType filterByType, IEnumerable tags, bool searchByTags, bool searchByFilter, bool withoutTags, - bool excludeSubject, Guid subjectId) + bool excludeSubject, Guid subjectId, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { var q1 = GetFolderQuery(filesDbContext, r => r.ParentId == parentId).AsNoTracking(); - q1 = BuildRoomsQuery(filesDbContext, q1, filterByType, tags, subjectId, searchByTags, withoutTags, searchByFilter, true, excludeSubject); + q1 = BuildRoomsQuery(filesDbContext, q1, filterByType, tags, subjectId, searchByTags, withoutTags, searchByFilter, true, excludeSubject, subjectFilter, subjectEntriesIds); if (searchByTags) { @@ -1520,11 +1529,11 @@ internal class FolderDao : AbstractDao, IFolderDao } private IQueryable BuildRoomsWithSubfoldersQuery(FilesDbContext filesDbContext, IEnumerable roomsIds, FolderType filterByType, IEnumerable tags, bool searchByTags, bool searchByFilter, bool withoutTags, - bool withoutMe, Guid ownerId) + bool withoutMe, Guid ownerId, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { var q1 = GetFolderQuery(filesDbContext, f => roomsIds.Contains(f.Id)).AsNoTracking(); - q1 = BuildRoomsQuery(filesDbContext, q1, filterByType, tags, ownerId, searchByTags, withoutTags, searchByFilter, true, withoutMe); + q1 = BuildRoomsQuery(filesDbContext, q1, filterByType, tags, ownerId, searchByTags, withoutTags, searchByFilter, true, withoutMe, subjectFilter, subjectEntriesIds); if (searchByTags) { diff --git a/products/ASC.Files/Core/Core/FileStorageService.cs b/products/ASC.Files/Core/Core/FileStorageService.cs index 16b2209db4..5d1c771132 100644 --- a/products/ASC.Files/Core/Core/FileStorageService.cs +++ b/products/ASC.Files/Core/Core/FileStorageService.cs @@ -272,7 +272,8 @@ public class FileStorageService //: IFileStorageService bool withoutTags = false, IEnumerable tagNames = null, bool excludeSubject = false, - ProviderFilter provider = ProviderFilter.None) + ProviderFilter provider = ProviderFilter.None, + SubjectFilter subjectFilter = SubjectFilter.Owner) { var subjectId = string.IsNullOrEmpty(subject) ? Guid.Empty : new Guid(subject); @@ -322,7 +323,7 @@ public class FileStorageService //: IFileStorageService try { (entries, total) = await _entryManager.GetEntriesAsync(parent, from, count, filterType, subjectGroup, subjectId, searchText, searchInContent, withSubfolders, orderBy, searchArea, - withoutTags, tagNames, excludeSubject, provider); + withoutTags, tagNames, excludeSubject, provider, subjectFilter); } catch (Exception e) { diff --git a/products/ASC.Files/Core/Core/Security/FileSecurity.cs b/products/ASC.Files/Core/Core/Security/FileSecurity.cs index 92bc68f898..7abdca4c07 100644 --- a/products/ASC.Files/Core/Core/Security/FileSecurity.cs +++ b/products/ASC.Files/Core/Core/Security/FileSecurity.cs @@ -1013,23 +1013,28 @@ public class FileSecurity : IFileSecurity } public async Task> GetVirtualRoomsAsync(FilterType filterType, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders, - SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider) + SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter) { + var securityDao = _daoFactory.GetSecurityDao(); + + var subjectEntries = subjectFilter is SubjectFilter.Member + ? await securityDao.GetSharesAsync(new[] { subjectId }).Where(r => r.EntryType == FileEntryType.Folder).Select(r => r.EntryId.ToString()).ToListAsync() + : null; + if (_fileSecurityCommon.IsDocSpaceAdministrator(_authContext.CurrentAccount.ID)) { - return await GetVirtualRoomsForDocSpaceAdminAsync(filterType, subjectId, searchText, searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider); + return await GetVirtualRoomsForDocSpaceAdminAsync(filterType, subjectId, searchText, searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider, subjectFilter, subjectEntries); } - var securityDao = _daoFactory.GetSecurityDao(); - var subjects = GetUserSubjects(_authContext.CurrentAccount.ID); - var records = await securityDao.GetSharesAsync(subjects).ToListAsync(); + var currentUserSubjects = GetUserSubjects(_authContext.CurrentAccount.ID); + var currentUsersRecords = await securityDao.GetSharesAsync(currentUserSubjects).ToListAsync(); var thirdpartyIds = await GetThirdpartyRoomsIdsAsync(searchArea); var entries = new List(); - var rooms = await GetVirtualRoomsForUserAsync(records.Where(r => r.EntryId is int), Array.Empty(), subjects, filterType, subjectId, searchText, searchInContent, - withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider); - var thirdPartyRooms = await GetVirtualRoomsForUserAsync(records.Where(r => r.EntryId is string), thirdpartyIds, subjects, filterType, subjectId, searchText, - searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider); + var rooms = await GetVirtualRoomsForUserAsync(currentUsersRecords.Where(r => r.EntryId is int), Array.Empty(), currentUserSubjects, filterType, subjectId, searchText, searchInContent, + withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider, subjectFilter, subjectEntries); + var thirdPartyRooms = await GetVirtualRoomsForUserAsync(currentUsersRecords.Where(r => r.EntryId is string), thirdpartyIds, currentUserSubjects, filterType, subjectId, searchText, + searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider, subjectFilter, subjectEntries); entries.AddRange(rooms); entries.AddRange(thirdPartyRooms); @@ -1065,7 +1070,7 @@ public class FileSecurity : IFileSecurity } private async Task> GetVirtualRoomsForDocSpaceAdminAsync(FilterType filterType, Guid subjectId, string search, bool searchInContent, bool withSubfolders, - SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider) + SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntries) { var folderDao = _daoFactory.GetFolderDao(); var folderThirdPartyDao = _daoFactory.GetFolderDao(); @@ -1082,8 +1087,8 @@ public class FileSecurity : IFileSecurity var roomsFolderId = await _globalFolder.GetFolderVirtualRoomsAsync(_daoFactory); var thirdPartyRoomsIds = await providerDao.GetProvidersInfoAsync(FolderType.VirtualRooms).Select(p => p.FolderId).ToListAsync(); - var roomsEntries = await folderDao.GetRoomsAsync(roomsFolderId, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider).ToListAsync(); - var thirdPartyRoomsEntries = await folderThirdPartyDao.GetRoomsAsync(Array.Empty(), thirdPartyRoomsIds, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider) + var roomsEntries = await folderDao.GetRoomsAsync(roomsFolderId, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntries).ToListAsync(); + var thirdPartyRoomsEntries = await folderThirdPartyDao.GetRoomsAsync(Array.Empty(), thirdPartyRoomsIds, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntries) .ToListAsync(); foldersInt.AddRange(roomsEntries); @@ -1114,8 +1119,8 @@ public class FileSecurity : IFileSecurity var archiveFolderId = await _globalFolder.GetFolderArchiveAsync(_daoFactory); var thirdPartyRoomsIds = await providerDao.GetProvidersInfoAsync(FolderType.Archive).Select(p => p.FolderId).ToListAsync(); - var roomsEntries = await folderDao.GetRoomsAsync(archiveFolderId, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider).ToListAsync(); - var thirdPartyRoomsEntries = await folderThirdPartyDao.GetRoomsAsync(Array.Empty(), thirdPartyRoomsIds, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider) + var roomsEntries = await folderDao.GetRoomsAsync(archiveFolderId, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntries).ToListAsync(); + var thirdPartyRoomsEntries = await folderThirdPartyDao.GetRoomsAsync(Array.Empty(), thirdPartyRoomsIds, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntries) .ToListAsync(); foldersInt.AddRange(roomsEntries); @@ -1154,7 +1159,7 @@ public class FileSecurity : IFileSecurity } private async Task> GetVirtualRoomsForUserAsync(IEnumerable records, IEnumerable proivdersIds, List subjects, FilterType filterType, Guid subjectId, string search, - bool searchInContent, bool withSubfolders, SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider) + bool searchInContent, bool withSubfolders, SearchArea searchArea, bool withoutTags, IEnumerable tagNames, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntries) { var folderDao = _daoFactory.GetFolderDao(); var fileDao = _daoFactory.GetFileDao(); @@ -1211,7 +1216,7 @@ public class FileSecurity : IFileSecurity return false; }; - var fileEntries = await folderDao.GetRoomsAsync(rootFoldersIds, roomsIds.Keys, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider) + var fileEntries = await folderDao.GetRoomsAsync(rootFoldersIds, roomsIds.Keys, filterType, tagNames, subjectId, search, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntries) .Where(filter).ToListAsync(); await SetTagsAsync(fileEntries); diff --git a/products/ASC.Files/Core/Core/SubjectFilter.cs b/products/ASC.Files/Core/Core/SubjectFilter.cs new file mode 100644 index 0000000000..d933b0eaa4 --- /dev/null +++ b/products/ASC.Files/Core/Core/SubjectFilter.cs @@ -0,0 +1,33 @@ +// (c) Copyright Ascensio System SIA 2010-2022 +// +// This program is a free software product. +// You can redistribute it and/or modify it under the terms +// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software +// Foundation. In accordance with Section 7(a) of the GNU AGPL 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 details, see +// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html +// +// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. +// +// The interactive user interfaces in modified source and object code versions of the Program must +// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. +// +// Pursuant to Section 7(b) of the License you must retain the original Product logo when +// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under +// trademark law for use of our trademarks. +// +// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing +// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +namespace ASC.Files.Core.Core; + +public enum SubjectFilter +{ + Owner = 0, + Member = 1, +} \ No newline at end of file diff --git a/products/ASC.Files/Core/Core/Thirdparty/Box/BoxFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/Box/BoxFolderDao.cs index a29a13fe07..57f44f2d8b 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/Box/BoxFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/Box/BoxFolderDao.cs @@ -75,7 +75,7 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao } public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, - bool withoutTags, bool excludeSubject, ProviderFilter provider) + bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.Box)) { @@ -85,7 +85,7 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -98,7 +98,7 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao } public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, - bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.Box)) { @@ -108,7 +108,7 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Core/Thirdparty/Dropbox/DropboxFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/Dropbox/DropboxFolderDao.cs index 629826c207..895460458d 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/Dropbox/DropboxFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/Dropbox/DropboxFolderDao.cs @@ -77,7 +77,7 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao return GetRootFolderAsync(fileId); } - public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.DropBox)) { @@ -87,7 +87,7 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -99,7 +99,7 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao return rooms; } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.DropBox)) { @@ -109,7 +109,7 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Core/Thirdparty/GoogleDrive/GoogleDriveFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/GoogleDrive/GoogleDriveFolderDao.cs index eef0faa3d4..5a4cf25c1d 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/GoogleDrive/GoogleDriveFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/GoogleDrive/GoogleDriveFolderDao.cs @@ -74,7 +74,7 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao return GetRootFolderAsync(""); } - public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.GoogleDrive)) { @@ -84,7 +84,7 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -96,7 +96,8 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao return rooms; } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, + IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.GoogleDrive)) { @@ -106,7 +107,7 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Core/Thirdparty/IThirdPartyProviderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/IThirdPartyProviderDao.cs index 23edc84812..95bf37b434 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/IThirdPartyProviderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/IThirdPartyProviderDao.cs @@ -456,11 +456,19 @@ internal abstract class ThirdPartyProviderDao : ThirdPartyProviderDao, IDispo return rooms.Where(f => f != null && (f.FolderType == filter || filter == FolderType.DEFAULT)); } - protected IAsyncEnumerable> FilterBySubject(IAsyncEnumerable> rooms, Guid subjectId, bool excludeSubject) + protected IAsyncEnumerable> FilterBySubject(IAsyncEnumerable> rooms, Guid subjectId, bool excludeSubject, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds = null) { if (subjectId != Guid.Empty) { - rooms = excludeSubject ? rooms.Where(f => f != null && f.CreateBy != subjectId) : rooms.Where(f => f != null && f.CreateBy == subjectId); + if (subjectFilter == SubjectFilter.Owner) + { + rooms = excludeSubject ? rooms.Where(f => f != null && f.CreateBy != subjectId) : rooms.Where(f => f != null && f.CreateBy == subjectId); + } + else if (subjectFilter == SubjectFilter.Member) + { + rooms = excludeSubject ? rooms.Where(f => f != null && f.CreateBy != subjectId && !subjectEntriesIds.Contains(f.Id)) + : rooms.Where(f => f != null && (f.CreateBy == subjectId || subjectEntriesIds.Contains(f.Id))); + } } return rooms; diff --git a/products/ASC.Files/Core/Core/Thirdparty/OneDrive/OneDriveFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/OneDrive/OneDriveFolderDao.cs index 74ebf2dd34..ce31ffa72a 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/OneDrive/OneDriveFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/OneDrive/OneDriveFolderDao.cs @@ -74,7 +74,7 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao return GetRootFolderAsync(fileId); } - public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.OneDrive)) { @@ -84,7 +84,7 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -96,7 +96,7 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao return rooms; } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.OneDrive)) { @@ -106,7 +106,7 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Core/Thirdparty/ProviderDao/ProviderFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/ProviderDao/ProviderFolderDao.cs index 73f5258784..07767bfcae 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/ProviderDao/ProviderFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/ProviderDao/ProviderFolderDao.cs @@ -90,11 +90,11 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao return folderDao.GetRootFolderByFileAsync(selector.ConvertId(fileId)); } - public async IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public async IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { var selector = GetSelector(parentId); var folderDao = selector.GetFolderDao(parentId); - var rooms = folderDao.GetRoomsAsync(selector.ConvertId(parentId), filterType, tags, subjectId, searchText, withSubfolders, withoutTags, excludeSubject, provider); + var rooms = folderDao.GetRoomsAsync(selector.ConvertId(parentId), filterType, tags, subjectId, searchText, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntriesIds); var result = await FilterByProvider(rooms.Where(r => r != null), provider).ToListAsync(); @@ -106,7 +106,7 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao } } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { var result = AsyncEnumerable.Empty>(); @@ -126,7 +126,7 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao { var folderDao = selectorLocal.GetFolderDao(matchedId.FirstOrDefault()); - return folderDao.GetRoomsAsync(parentsIds, matchedId.Select(selectorLocal.ConvertId).ToList(), filterType, tags, subjectId, searchText, withSubfolders, withoutTags, excludeSubject, provider); + return folderDao.GetRoomsAsync(parentsIds, matchedId.Select(selectorLocal.ConvertId).ToList(), filterType, tags, subjectId, searchText, withSubfolders, withoutTags, excludeSubject, provider, subjectFilter, subjectEntriesIds); }) .Where(r => r != null)); } diff --git a/products/ASC.Files/Core/Core/Thirdparty/SharePoint/SharePointFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/SharePoint/SharePointFolderDao.cs index a8e1388b26..d5b26d0ca6 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/SharePoint/SharePointFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/SharePoint/SharePointFolderDao.cs @@ -80,7 +80,7 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao return Task.FromResult(ProviderInfo.ToFolder(ProviderInfo.RootFolder)); } - public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.SharePoint)) { @@ -90,7 +90,7 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -102,7 +102,7 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao return rooms; } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.SharePoint)) { @@ -112,7 +112,7 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxFolderDao.cs b/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxFolderDao.cs index b2dfba995b..fdadca38d5 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxFolderDao.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxFolderDao.cs @@ -79,7 +79,7 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao return Task.FromResult(ToFolder(RootFolder())); } - public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(string parentId, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.kDrive && provider != ProviderFilter.WebDav && provider != ProviderFilter.Yandex)) { @@ -89,7 +89,7 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao var rooms = GetFoldersAsync(parentId); rooms = FilterByRoomType(rooms, filterType); - rooms = FilterBySubject(rooms, subjectId, excludeSubject); + rooms = FilterBySubject(rooms, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { @@ -101,7 +101,8 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao return rooms; } - public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider) + public IAsyncEnumerable> GetRoomsAsync(IEnumerable parentsIds, IEnumerable roomsIds, FilterType filterType, IEnumerable tags, Guid subjectId, string searchText, bool withSubfolders, bool withoutTags, bool excludeSubject, ProviderFilter provider, + SubjectFilter subjectFilter, IEnumerable subjectEntriesIds) { if (CheckInvalidFilter(filterType) || (provider != ProviderFilter.None && provider != ProviderFilter.kDrive && provider != ProviderFilter.WebDav && provider != ProviderFilter.Yandex)) { @@ -111,7 +112,7 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao var folders = roomsIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false)); folders = FilterByRoomType(folders, filterType); - folders = FilterBySubject(folders, subjectId, excludeSubject); + folders = FilterBySubject(folders, subjectId, excludeSubject, subjectFilter, subjectEntriesIds); if (!string.IsNullOrEmpty(searchText)) { diff --git a/products/ASC.Files/Core/Utils/EntryManager.cs b/products/ASC.Files/Core/Utils/EntryManager.cs index 5db5bbb1fa..cf0cbefdfa 100644 --- a/products/ASC.Files/Core/Utils/EntryManager.cs +++ b/products/ASC.Files/Core/Utils/EntryManager.cs @@ -388,7 +388,7 @@ public class EntryManager public async Task<(IEnumerable Entries, int Total)> GetEntriesAsync(Folder parent, int from, int count, FilterType filterType, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy, SearchArea searchArea = SearchArea.Active, bool withoutTags = false, IEnumerable tagNames = null, - bool excludeSubject = false, ProviderFilter provider = ProviderFilter.None) + bool excludeSubject = false, ProviderFilter provider = ProviderFilter.None, SubjectFilter subjectFilter = SubjectFilter.Owner) { var total = 0; @@ -471,7 +471,7 @@ public class EntryManager } else if ((parent.FolderType == FolderType.VirtualRooms || parent.FolderType == FolderType.Archive) && !parent.ProviderEntry) { - entries = await _fileSecurity.GetVirtualRoomsAsync(filterType, subjectId, searchText, searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider); + entries = await _fileSecurity.GetVirtualRoomsAsync(filterType, subjectId, searchText, searchInContent, withSubfolders, searchArea, withoutTags, tagNames, excludeSubject, provider, subjectFilter); CalculateTotal(); } diff --git a/products/ASC.Files/Server/Api/VirtualRoomsController.cs b/products/ASC.Files/Server/Api/VirtualRoomsController.cs index af91083d77..dc41f55be2 100644 --- a/products/ASC.Files/Server/Api/VirtualRoomsController.cs +++ b/products/ASC.Files/Server/Api/VirtualRoomsController.cs @@ -653,7 +653,7 @@ public class VirtualRoomsCommonController : ApiControllerBase /// [HttpGet("rooms")] public async Task> GetRoomsFolderAsync(RoomFilterType? type, string subjectId, bool? searchInContent, bool? withSubfolders, SearchArea? searchArea, bool? withoutTags, string tags, bool? excludeSubject, - ProviderFilter? provider) + ProviderFilter? provider, SubjectFilter? subjectFilter) { ErrorIfNotDocSpace(); @@ -685,7 +685,7 @@ public class VirtualRoomsCommonController : ApiControllerBase var content = await _fileStorageServiceInt.GetFolderItemsAsync(parentId, startIndex, count, filter, false, subjectId, filterValue, searchInContent ?? false, withSubfolders ?? false, orderBy, searchArea ?? SearchArea.Active, withoutTags ?? false, tagNames, excludeSubject ?? false, - provider ?? ProviderFilter.None); + provider ?? ProviderFilter.None, subjectFilter ?? SubjectFilter.Owner); var dto = await _folderContentDtoHelper.GetAsync(content, startIndex); diff --git a/products/ASC.People/Server/Api/UserController.cs b/products/ASC.People/Server/Api/UserController.cs index 67a96beb38..1f1b2e66ad 100644 --- a/products/ASC.People/Server/Api/UserController.cs +++ b/products/ASC.People/Server/Api/UserController.cs @@ -22,18 +22,18 @@ // // All the Product's GUI elements, including illustrations and icon sets, as well as technical writing // content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 -// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - -using ASC.Common.Log; - +// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + +using ASC.Common.Log; + namespace ASC.People.Api; public class UserController : PeopleControllerBase { private Tenant Tenant => _apiContext.Tenant; - private readonly ICache _cache; - private readonly TenantManager _tenantManager; + private readonly ICache _cache; + private readonly TenantManager _tenantManager; private readonly CookiesManager _cookiesManager; private readonly CoreBaseSettings _coreBaseSettings; private readonly CustomNamingPeople _customNamingPeople; @@ -56,19 +56,19 @@ public class UserController : PeopleControllerBase private readonly StudioNotifyService _studioNotifyService; private readonly MessageService _messageService; private readonly AuthContext _authContext; - private readonly SetupInfo _setupInfo; - private readonly SettingsManager _settingsManager; - private readonly RoomLinkService _roomLinkService; + private readonly SetupInfo _setupInfo; + private readonly SettingsManager _settingsManager; + private readonly RoomLinkService _roomLinkService; private readonly FileSecurity _fileSecurity; private readonly IQuotaService _quotaService; private readonly CountRoomAdminChecker _countRoomAdminChecker; private readonly UsersQuotaSyncOperation _usersQuotaSyncOperation; private readonly CountUserChecker _countUserChecker; private readonly UsersInRoomChecker _usersInRoomChecker; - + public UserController( - ICache cache, - TenantManager tenantManager, + ICache cache, + TenantManager tenantManager, CookiesManager cookiesManager, CoreBaseSettings coreBaseSettings, CustomNamingPeople customNamingPeople, @@ -96,10 +96,10 @@ public class UserController : PeopleControllerBase PermissionContext permissionContext, ApiContext apiContext, UserPhotoManager userPhotoManager, - IHttpClientFactory httpClientFactory, - IHttpContextAccessor httpContextAccessor, - SettingsManager settingsManager, - RoomLinkService roomLinkService, + IHttpClientFactory httpClientFactory, + IHttpContextAccessor httpContextAccessor, + SettingsManager settingsManager, + RoomLinkService roomLinkService, FileSecurity fileSecurity, UsersQuotaSyncOperation usersQuotaSyncOperation, CountRoomAdminChecker countRoomAdminChecker, @@ -108,8 +108,8 @@ public class UserController : PeopleControllerBase IQuotaService quotaService) : base(userManager, permissionContext, apiContext, userPhotoManager, httpClientFactory, httpContextAccessor) { - _cache = cache; - _tenantManager = tenantManager; + _cache = cache; + _tenantManager = tenantManager; _cookiesManager = cookiesManager; _coreBaseSettings = coreBaseSettings; _customNamingPeople = customNamingPeople; @@ -132,14 +132,14 @@ public class UserController : PeopleControllerBase _studioNotifyService = studioNotifyService; _messageService = messageService; _authContext = authContext; - _setupInfo = setupInfo; - _settingsManager = settingsManager; - _roomLinkService = roomLinkService; + _setupInfo = setupInfo; + _settingsManager = settingsManager; + _roomLinkService = roomLinkService; _fileSecurity = fileSecurity; _countRoomAdminChecker = countRoomAdminChecker; _countUserChecker = activeUsersChecker; _usersInRoomChecker = usersInRoomChecker; - _quotaService = quotaService; + _quotaService = quotaService; _usersQuotaSyncOperation = usersQuotaSyncOperation; } @@ -157,7 +157,7 @@ public class UserController : PeopleControllerBase if (string.IsNullOrEmpty(inDto.Password)) { - inDto.Password = UserManagerWrapper.GeneratePassword(); + inDto.Password = UserManagerWrapper.GeneratePassword(); } else { @@ -185,16 +185,16 @@ public class UserController : PeopleControllerBase UpdateContacts(inDto.Contacts, user); - _cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5)); + _cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5)); user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, false, false, inDto.IsUser, false, true, true); user.ActivationStatus = EmployeeActivationStatus.Activated; await UpdateDepartments(inDto.Department, user); - if (inDto.Files != _userPhotoManager.GetDefaultPhotoAbsoluteWebPath()) + if (inDto.Files != _userPhotoManager.GetDefaultPhotoAbsoluteWebPath()) { - await UpdatePhotoUrl(inDto.Files, user); + await UpdatePhotoUrl(inDto.Files, user); } return await _employeeFullDtoHelper.GetFull(user); @@ -206,29 +206,29 @@ public class UserController : PeopleControllerBase { _apiContext.AuthByClaim(); - _permissionContext.DemandPermissions(Constants.Action_AddRemoveUser); - - var options = inDto.FromInviteLink ? await _roomLinkService.GetOptionsAsync(inDto.Key, inDto.Email, inDto.Type) : null; - - if (options != null && !options.IsCorrect) - { - throw new SecurityException(FilesCommonResource.ErrorMessage_InvintationLink); + _permissionContext.DemandPermissions(Constants.Action_AddRemoveUser); + + var options = inDto.FromInviteLink ? await _roomLinkService.GetOptionsAsync(inDto.Key, inDto.Email, inDto.Type) : null; + + if (options != null && !options.IsCorrect) + { + throw new SecurityException(FilesCommonResource.ErrorMessage_InvintationLink); } - + inDto.Type = options != null ? options.EmployeeType : inDto.Type; - var user = new UserInfo(); - - var byEmail = options?.LinkType == LinkType.InvintationByEmail; - - if (byEmail) - { - user = _userManager.GetUserByEmail(inDto.Email); - - if (user == Constants.LostUser || user.ActivationStatus != EmployeeActivationStatus.Pending) - { - throw new SecurityException(FilesCommonResource.ErrorMessage_InvintationLink); - } + var user = new UserInfo(); + + var byEmail = options?.LinkType == LinkType.InvintationByEmail; + + if (byEmail) + { + user = _userManager.GetUserByEmail(inDto.Email); + + if (user == Constants.LostUser || user.ActivationStatus != EmployeeActivationStatus.Pending) + { + throw new SecurityException(FilesCommonResource.ErrorMessage_InvintationLink); + } } inDto.PasswordHash = (inDto.PasswordHash ?? "").Trim(); @@ -238,7 +238,7 @@ public class UserController : PeopleControllerBase if (string.IsNullOrEmpty(inDto.Password)) { - inDto.Password = UserManagerWrapper.GeneratePassword(); + inDto.Password = UserManagerWrapper.GeneratePassword(); } else { @@ -249,8 +249,8 @@ public class UserController : PeopleControllerBase //Validate email var address = new MailAddress(inDto.Email); - user.Email = address.Address; - //Set common fields + user.Email = address.Address; + //Set common fields user.CultureName = inDto.CultureName; user.FirstName = inDto.Firstname; user.LastName = inDto.Lastname; @@ -265,56 +265,56 @@ public class UserController : PeopleControllerBase user.WorkFromDate = inDto.Worksfrom != null && inDto.Worksfrom != DateTime.MinValue ? _tenantUtil.DateTimeFromUtc(inDto.Worksfrom) : DateTime.UtcNow.Date; UpdateContacts(inDto.Contacts, user); - _cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5)); + _cache.Insert("REWRITE_URL" + _tenantManager.GetCurrentTenant().Id, HttpContext.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5)); user = await _userManagerWrapper.AddUser(user, inDto.PasswordHash, inDto.FromInviteLink, true, inDto.Type == EmployeeType.User, inDto.FromInviteLink, true, true, byEmail, inDto.Type == EmployeeType.DocSpaceAdmin); await UpdateDepartments(inDto.Department, user); - if (inDto.Files != _userPhotoManager.GetDefaultPhotoAbsoluteWebPath()) + if (inDto.Files != _userPhotoManager.GetDefaultPhotoAbsoluteWebPath()) { - await UpdatePhotoUrl(inDto.Files, user); - } - - if (options != null && options.LinkType == LinkType.InvintationToRoom) - { - var success = int.TryParse(options.RoomId, out var id); - - if (success) - { - await _usersInRoomChecker.CheckAppend(); + await UpdatePhotoUrl(inDto.Files, user); + } + + if (options != null && options.LinkType == LinkType.InvintationToRoom) + { + var success = int.TryParse(options.RoomId, out var id); + + if (success) + { + await _usersInRoomChecker.CheckAppend(); await _fileSecurity.ShareAsync(id, FileEntryType.Folder, user.Id, options.Share); - } - else - { - await _usersInRoomChecker.CheckAppend(); + } + else + { + await _usersInRoomChecker.CheckAppend(); await _fileSecurity.ShareAsync(options.RoomId, FileEntryType.Folder, user.Id, options.Share); - } - } - - var messageAction = inDto.IsUser ? MessageAction.GuestCreated : MessageAction.UserCreated; + } + } + + var messageAction = inDto.IsUser ? MessageAction.GuestCreated : MessageAction.UserCreated; _messageService.Send(messageAction, _messageTarget.Create(user.Id), user.DisplayUserName(false, _displayUserSettingsHelper)); return await _employeeFullDtoHelper.GetFull(user); } - [HttpPost("invite")] - public async IAsyncEnumerable InviteUsersAsync(InviteUsersRequestDto inDto) - { - foreach (var invite in inDto.Invitations) - { - var user = await _userManagerWrapper.AddInvitedUserAsync(invite.Email, invite.Type); - var link = _roomLinkService.GetInvitationLink(user.Email, invite.Type, _authContext.CurrentAccount.ID); - - _studioNotifyService.SendDocSpaceInvite(user.Email, link); - _logger.Debug(link); - } - - var users = _userManager.GetUsers().Where(u => u.ActivationStatus == EmployeeActivationStatus.Pending); - - foreach (var user in users) - { - yield return await _employeeDtoHelper.Get(user); - } + [HttpPost("invite")] + public async IAsyncEnumerable InviteUsersAsync(InviteUsersRequestDto inDto) + { + foreach (var invite in inDto.Invitations) + { + var user = await _userManagerWrapper.AddInvitedUserAsync(invite.Email, invite.Type); + var link = _roomLinkService.GetInvitationLink(user.Email, invite.Type, _authContext.CurrentAccount.ID); + + _studioNotifyService.SendDocSpaceInvite(user.Email, link); + _logger.Debug(link); + } + + var users = _userManager.GetUsers().Where(u => u.ActivationStatus == EmployeeActivationStatus.Pending); + + foreach (var user in users) + { + yield return await _employeeDtoHelper.Get(user); + } } [HttpPut("{userid}/password")] @@ -328,12 +328,12 @@ public class UserController : PeopleControllerBase if (!_userManager.UserExists(user)) { - return null; + return null; } - if (_userManager.IsSystemUser(user.Id)) + if (_userManager.IsSystemUser(user.Id)) { - throw new SecurityException(); + throw new SecurityException(); } if (!string.IsNullOrEmpty(inDto.Email)) @@ -468,10 +468,10 @@ public class UserController : PeopleControllerBase list = list.Where(x => x.FirstName != null && x.FirstName.IndexOf(query, StringComparison.OrdinalIgnoreCase) > -1 || (x.LastName != null && x.LastName.IndexOf(query, StringComparison.OrdinalIgnoreCase) != -1) || (x.UserName != null && x.UserName.IndexOf(query, StringComparison.OrdinalIgnoreCase) != -1) || (x.Email != null && x.Email.IndexOf(query, StringComparison.OrdinalIgnoreCase) != -1) || (x.ContactsList != null && x.ContactsList.Any(y => y.IndexOf(query, StringComparison.OrdinalIgnoreCase) != -1))); - - foreach (var item in list) - { - yield return await _employeeFullDtoHelper.GetFull(item); + + foreach (var item in list) + { + yield return await _employeeFullDtoHelper.GetFull(item); } } @@ -480,7 +480,7 @@ public class UserController : PeopleControllerBase { return GetByStatus(EmployeeStatus.Active); } - + [AllowNotPayment] [HttpGet("email")] public async Task GetByEmail([FromQuery] string email) @@ -497,7 +497,7 @@ public class UserController : PeopleControllerBase } return await _employeeFullDtoHelper.GetFull(user); - } + } [AllowNotPayment] [Authorize(AuthenticationSchemes = "confirm", Roles = "LinkInvite,Everyone")] @@ -506,18 +506,18 @@ public class UserController : PeopleControllerBase { if (_coreBaseSettings.Personal) { - throw new MethodAccessException("Method not available"); - } - - var isInvite = _httpContextAccessor.HttpContext.User.Claims - .Any(role => role.Type == ClaimTypes.Role && ConfirmTypeExtensions.TryParse(role.Value, out var confirmType) && confirmType == ConfirmType.LinkInvite); - - _apiContext.AuthByClaim(); + throw new MethodAccessException("Method not available"); + } + + var isInvite = _httpContextAccessor.HttpContext.User.Claims + .Any(role => role.Type == ClaimTypes.Role && ConfirmTypeExtensions.TryParse(role.Value, out var confirmType) && confirmType == ConfirmType.LinkInvite); + + _apiContext.AuthByClaim(); var user = _userManager.GetUserByUserName(username); if (user.Id == Constants.LostUser.Id) { - if (Guid.TryParse(username, out var userId)) + if (Guid.TryParse(username, out var userId)) { user = _userManager.GetUsers(userId); } @@ -530,12 +530,12 @@ public class UserController : PeopleControllerBase if (user.Id == Constants.LostUser.Id) { throw new ItemNotFoundException("User not found"); - } - - if (isInvite) - { + } + + if (isInvite) + { return await _employeeFullDtoHelper.GetSimple(user); - } + } return await _employeeFullDtoHelper.GetFull(user); } @@ -555,17 +555,17 @@ public class UserController : PeopleControllerBase _apiContext.SetDataFiltered(); } - return GetFullByFilter(status, groupId, null, null, null); + return GetFullByFilter(status, groupId, null, null, null, null); } [HttpGet("filter")] - public async IAsyncEnumerable GetFullByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isAdministrator) + public async IAsyncEnumerable GetFullByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isAdministrator, Payments? payments) { - var users = GetByFilter(employeeStatus, groupId, activationStatus, employeeType, isAdministrator); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); + var users = GetByFilter(employeeStatus, groupId, activationStatus, employeeType, isAdministrator, payments); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); } } @@ -590,30 +590,30 @@ public class UserController : PeopleControllerBase if (_coreBaseSettings.Personal) { throw new MethodAccessException("Method not available"); - } - - var groupId = Guid.Empty; - if ("group".Equals(_apiContext.FilterBy, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(_apiContext.FilterValue)) - { - groupId = new Guid(_apiContext.FilterValue); - } - - var users = _userManager.Search(query, EmployeeStatus.Active, groupId); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); + } + + var groupId = Guid.Empty; + if ("group".Equals(_apiContext.FilterBy, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(_apiContext.FilterValue)) + { + groupId = new Guid(_apiContext.FilterValue); + } + + var users = _userManager.Search(query, EmployeeStatus.Active, groupId); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); } } [HttpGet("simple/filter")] - public async IAsyncEnumerable GetSimpleByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isAdministrator) + public async IAsyncEnumerable GetSimpleByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isAdministrator, Payments? payments) { - var users = GetByFilter(employeeStatus, groupId, activationStatus, employeeType, isAdministrator); - - foreach (var user in users) - { - yield return await _employeeDtoHelper.Get(user); + var users = GetByFilter(employeeStatus, groupId, activationStatus, employeeType, isAdministrator, payments); + + foreach (var user in users) + { + yield return await _employeeDtoHelper.Get(user); } } @@ -644,7 +644,7 @@ public class UserController : PeopleControllerBase foreach (var user in users) { - if (user.Status != EmployeeStatus.Terminated) + if (user.Status != EmployeeStatus.Terminated) { continue; } @@ -654,43 +654,43 @@ public class UserController : PeopleControllerBase _queueWorkerRemove.Start(Tenant.Id, user, _securityContext.CurrentAccount.ID, false); } - _messageService.Send(MessageAction.UsersDeleted, _messageTarget.Create(users.Select(x => x.Id)), userNames); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); - } + _messageService.Send(MessageAction.UsersDeleted, _messageTarget.Create(users.Select(x => x.Id)), userNames); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); + } } [HttpPut("invite")] - public async IAsyncEnumerable ResendUserInvites(UpdateMembersRequestDto inDto) + public async IAsyncEnumerable ResendUserInvites(UpdateMembersRequestDto inDto) { - var users = inDto.UserIds - .Where(userId => !_userManager.IsSystemUser(userId)) - .Select(userId => _userManager.GetUsers(userId)) + var users = inDto.UserIds + .Where(userId => !_userManager.IsSystemUser(userId)) + .Select(userId => _userManager.GetUsers(userId)) .ToList(); - foreach (var user in users) + foreach (var user in users) { - if (user.IsActive) + if (user.IsActive) { - continue; + continue; } var viewer = _userManager.GetUsers(_securityContext.CurrentAccount.ID); if (viewer == null) { - throw new Exception(Resource.ErrorAccessDenied); + throw new Exception(Resource.ErrorAccessDenied); } - if (_userManager.IsDocSpaceAdmin(viewer) || viewer.Id == user.Id) + if (_userManager.IsDocSpaceAdmin(viewer) || viewer.Id == user.Id) { if (user.ActivationStatus == EmployeeActivationStatus.Activated) { user.ActivationStatus = EmployeeActivationStatus.NotActivated; } - if (user.ActivationStatus == (EmployeeActivationStatus.AutoGenerated | EmployeeActivationStatus.Activated)) + if (user.ActivationStatus == (EmployeeActivationStatus.AutoGenerated | EmployeeActivationStatus.Activated)) { user.ActivationStatus = EmployeeActivationStatus.AutoGenerated; } @@ -698,31 +698,31 @@ public class UserController : PeopleControllerBase await _userManager.UpdateUserInfoWithSyncCardDavAsync(user); } - if (user.ActivationStatus == EmployeeActivationStatus.Pending) + if (user.ActivationStatus == EmployeeActivationStatus.Pending) { - var type = _userManager.IsDocSpaceAdmin(user) ? EmployeeType.DocSpaceAdmin : - _userManager.IsUser(user) ? EmployeeType.User : EmployeeType.RoomAdmin; - - _studioNotifyService.SendDocSpaceInvite(user.Email, _roomLinkService.GetInvitationLink(user.Email, type, _authContext.CurrentAccount.ID)); - } - else + var type = _userManager.IsDocSpaceAdmin(user) ? EmployeeType.DocSpaceAdmin : + _userManager.IsUser(user) ? EmployeeType.User : EmployeeType.RoomAdmin; + + _studioNotifyService.SendDocSpaceInvite(user.Email, _roomLinkService.GetInvitationLink(user.Email, type, _authContext.CurrentAccount.ID)); + } + else { - _studioNotifyService.SendEmailActivationInstructions(user, user.Email); - } + _studioNotifyService.SendEmailActivationInstructions(user, user.Email); + } } - _messageService.Send(MessageAction.UsersSentActivationInstructions, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); - } + _messageService.Send(MessageAction.UsersSentActivationInstructions, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); + } } - [HttpGet("theme")] - public DarkThemeSettings GetTheme() + [HttpGet("theme")] + public DarkThemeSettings GetTheme() { - return _settingsManager.LoadForCurrentUser(); + return _settingsManager.LoadForCurrentUser(); } [HttpPut("theme")] @@ -740,15 +740,15 @@ public class UserController : PeopleControllerBase [AllowNotPayment] [HttpGet("@self")] - public async Task Self() + public async Task Self() { var user = _userManager.GetUser(_securityContext.CurrentAccount.ID, EmployeeFullDtoHelper.GetExpression(_apiContext)); - var result = await _employeeFullDtoHelper.GetFull(user); + var result = await _employeeFullDtoHelper.GetFull(user); - result.Theme = _settingsManager.LoadForCurrentUser().Theme; + result.Theme = _settingsManager.LoadForCurrentUser().Theme; - return result; + return result; } [AllowNotPayment] @@ -823,7 +823,7 @@ public class UserController : PeopleControllerBase { var error = _userManagerWrapper.SendUserPassword(inDto.Email); if (!string.IsNullOrEmpty(error)) - { + { _logger.ErrorPasswordRecovery(inDto.Email, error); } @@ -992,8 +992,8 @@ public class UserController : PeopleControllerBase } return await _employeeFullDtoHelper.GetFull(user); - } - + } + [HttpPut("status/{status}")] public async IAsyncEnumerable UpdateUserStatus(EmployeeStatus status, UpdateMembersRequestDto inDto) { @@ -1015,13 +1015,13 @@ public class UserController : PeopleControllerBase case EmployeeStatus.Active: if (user.Status == EmployeeStatus.Terminated) { - if (!_userManager.IsUser(user)) + if (!_userManager.IsUser(user)) { - await _countRoomAdminChecker.CheckAppend(); + await _countRoomAdminChecker.CheckAppend(); } - else - { - await _countUserChecker.CheckAppend(); + else + { + await _countUserChecker.CheckAppend(); } user.Status = EmployeeStatus.Active; @@ -1038,11 +1038,11 @@ public class UserController : PeopleControllerBase } } - _messageService.Send(MessageAction.UsersUpdatedStatus, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); + _messageService.Send(MessageAction.UsersUpdatedStatus, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); } } @@ -1064,33 +1064,33 @@ public class UserController : PeopleControllerBase switch (type) { - case EmployeeType.RoomAdmin: - await _countRoomAdminChecker.CheckAppend(); - _userManager.RemoveUserFromGroup(user.Id, Constants.GroupUser.ID); + case EmployeeType.RoomAdmin: + await _countRoomAdminChecker.CheckAppend(); + _userManager.RemoveUserFromGroup(user.Id, Constants.GroupUser.ID); _webItemSecurityCache.ClearCache(Tenant.Id); break; - case EmployeeType.User: - await _countUserChecker.CheckAppend(); + case EmployeeType.User: + await _countUserChecker.CheckAppend(); await _userManager.AddUserIntoGroup(user.Id, Constants.GroupUser.ID); _webItemSecurityCache.ClearCache(Tenant.Id); break; } } - _messageService.Send(MessageAction.UsersUpdatedType, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); - - foreach (var user in users) - { - yield return await _employeeFullDtoHelper.GetFull(user); + _messageService.Send(MessageAction.UsersUpdatedType, _messageTarget.Create(users.Select(x => x.Id)), users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); + + foreach (var user in users) + { + yield return await _employeeFullDtoHelper.GetFull(user); } - } + } [HttpGet("recalculatequota")] public void RecalculateQuota() { _permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); _usersQuotaSyncOperation.RecalculateQuota(_tenantManager.GetCurrentTenant()); } - + [HttpGet("checkrecalculatequota")] public TaskProgressDto CheckRecalculateQuota() { @@ -1107,31 +1107,31 @@ public class UserController : PeopleControllerBase .ToList(); foreach (var user in users) - { - if (inDto.Quota != -1) - { - var usedSpace = Math.Max(0, + { + if (inDto.Quota != -1) + { + var usedSpace = Math.Max(0, _quotaService.FindUserQuotaRows( - _tenantManager.GetCurrentTenant().Id, - user.Id - ) - .Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter)); - - var tenanSpaceQuota = _quotaService.GetTenantQuota(Tenant.Id).MaxTotalSize; - - if (tenanSpaceQuota < inDto.Quota || usedSpace > inDto.Quota) - { - continue; - } - } - - var quotaSettings = _settingsManager.Load(); - - _settingsManager.SaveForUser(new UserQuotaSettings { UserQuota = inDto.Quota }, user); - + _tenantManager.GetCurrentTenant().Id, + user.Id + ) + .Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter)); + + var tenanSpaceQuota = _quotaService.GetTenantQuota(Tenant.Id).MaxTotalSize; + + if (tenanSpaceQuota < inDto.Quota || usedSpace > inDto.Quota) + { + continue; + } + } + + var quotaSettings = _settingsManager.Load(); + + _settingsManager.SaveForUser(new UserQuotaSettings { UserQuota = inDto.Quota }, user); + yield return await _employeeFullDtoHelper.GetFull(user); - } - } + } + } private async Task UpdateDepartments(IEnumerable department, UserInfo user) @@ -1274,7 +1274,7 @@ public class UserController : PeopleControllerBase return string.Empty; } - private IQueryable GetByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isDocSpaceAdministrator) + private IQueryable GetByFilter(EmployeeStatus? employeeStatus, Guid? groupId, EmployeeActivationStatus? activationStatus, EmployeeType? employeeType, bool? isDocSpaceAdministrator, Payments? payments) { if (_coreBaseSettings.Personal) { @@ -1296,8 +1296,12 @@ public class UserController : PeopleControllerBase { switch (employeeType) { + case EmployeeType.DocSpaceAdmin: + includeGroups.Add(new List { Constants.GroupAdmin.ID }); + break; case EmployeeType.RoomAdmin: - excludeGroups.Add(Constants.GroupUser.ID); + excludeGroups.Add(Constants.GroupUser.ID); + excludeGroups.Add(Constants.GroupAdmin.ID); break; case EmployeeType.User: includeGroups.Add(new List { Constants.GroupUser.ID }); @@ -1305,6 +1309,19 @@ public class UserController : PeopleControllerBase } } + if (payments != null) + { + switch (payments) + { + case Payments.Paid: + excludeGroups.Add(Constants.GroupUser.ID); + break; + case Payments.Free: + includeGroups.Add(new List { Constants.GroupUser.ID }); + break; + } + } + if (isDocSpaceAdministrator.HasValue && isDocSpaceAdministrator.Value) { var adminGroups = new List @@ -1339,7 +1356,7 @@ public class UserController : PeopleControllerBase // lock (progressQueue.SynchRoot) // { // var task = progressQueue.GetItems().OfType().FirstOrDefault(t => (int)t.Id == TenantProvider.CurrentTenantID); - //var tenant = CoreContext.TenantManager.GetCurrentTenant(); + //var tenant = CoreContext.TenantManager.GetCurrentTenant(); //Cache.Insert("REWRITE_URL" + tenant.TenantId, HttpContext.Current.Request.GetUrlRewriter().ToString(), TimeSpan.FromMinutes(5)); // if (task != null && task.IsCompleted) // {