Files: added share pagination for room
This commit is contained in:
parent
5957d130a9
commit
09ed128fd0
@ -194,6 +194,51 @@ internal abstract class SecurityBaseDao<T> : AbstractDao
|
||||
|
||||
return InternalGetPureShareRecordsAsync(entry);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<FileShareRecord> GetRoomSharesAsync(Folder<T> room, ShareFilterType filterType, int offset = 0, int count = -1)
|
||||
{
|
||||
if (room == null || !DocSpaceHelper.IsRoom(room.FolderType) || count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
await using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var q = await GetPureSharesQuery(room, filterType, filesDbContext);
|
||||
|
||||
if (filterType == ShareFilterType.User)
|
||||
{
|
||||
q = q.Join(filesDbContext.Users, s => s.Subject, u => u.Id, (s, u) => new { s, u })
|
||||
.OrderBy(r => r.u.ActivationStatus)
|
||||
.ThenBy(r => r.s.Share == FileShare.RoomAdmin ? 0 :
|
||||
r.s.Share == FileShare.Collaborator ? 1 :
|
||||
r.s.Share == FileShare.Editing ? 2 :
|
||||
r.s.Share == FileShare.FillForms ? 3 :
|
||||
r.s.Share == FileShare.Review ? 4 :
|
||||
r.s.Share == FileShare.Comment ? 5 :
|
||||
r.s.Share == FileShare.Read ? 6 : 7)
|
||||
.Select(r => r.s);
|
||||
}
|
||||
else
|
||||
{
|
||||
q = q.OrderBy(s => s.Share);
|
||||
}
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
q = q.Skip(offset);
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
q = q.Take(count);
|
||||
}
|
||||
|
||||
await foreach (var r in q.ToAsyncEnumerable())
|
||||
{
|
||||
yield return await ToFileShareRecordAsync(r);
|
||||
}
|
||||
}
|
||||
|
||||
internal async IAsyncEnumerable<FileShareRecord> InternalGetPureShareRecordsAsync(FileEntry<T> entry)
|
||||
{
|
||||
@ -288,6 +333,32 @@ internal abstract class SecurityBaseDao<T> : AbstractDao
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<IQueryable<DbFilesSecurity>> GetPureSharesQuery(FileEntry<T> entry, ShareFilterType filterType, FilesDbContext filesDbContext)
|
||||
{
|
||||
var entryId = await MappingIDAsync(entry.Id);
|
||||
|
||||
var q = filesDbContext.Security.AsNoTracking()
|
||||
.Where(s => s.TenantId == TenantID && s.EntryId == entryId.ToString() && s.EntryType == entry.FileEntryType);
|
||||
|
||||
switch (filterType)
|
||||
{
|
||||
case ShareFilterType.User:
|
||||
q = q.Where(s => s.SubjectType == SubjectType.UserOrGroup);
|
||||
break;
|
||||
case ShareFilterType.InvitationLink:
|
||||
q = q.Where(s => s.SubjectType == SubjectType.InvitationLink);
|
||||
break;
|
||||
case ShareFilterType.ExternalLink:
|
||||
q = q.Where(s => s.SubjectType == SubjectType.ExternalLink);
|
||||
break;
|
||||
case ShareFilterType.Link:
|
||||
q = q.Where(s => s.SubjectType == SubjectType.InvitationLink || s.SubjectType == SubjectType.ExternalLink);
|
||||
break;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
[Scope]
|
||||
|
@ -2420,6 +2420,16 @@ public class FileStorageService //: IFileStorageService
|
||||
return await _fileSharing.GetSharedInfoShortFolderAsync(folderId);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<AceWrapper> GetRoomSharedInfoAsync<T>(T roomId, ShareFilterType filterType, int offset, int count)
|
||||
{
|
||||
var room = await GetFolderDao<T>().GetFolderAsync(roomId).NotFoundIfNull();
|
||||
|
||||
await foreach (var ace in _fileSharing.GetRoomSharedInfoAsync(room, filterType, offset, count))
|
||||
{
|
||||
yield return ace;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> SetAceObjectAsync<T>(AceCollection<T> aceCollection, bool notify)
|
||||
{
|
||||
var fileDao = GetFileDao<T>();
|
||||
|
@ -1118,6 +1118,11 @@ public class FileSecurity : IFileSecurity
|
||||
return await _daoFactory.GetSecurityDao<T>().GetSharesAsync(entry);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<FileShareRecord> GetRoomSharesAsync<T>(Folder<T> room, ShareFilterType filterType, int offset, int count)
|
||||
{
|
||||
return _daoFactory.GetSecurityDao<T>().GetRoomSharesAsync(room, filterType, offset, count);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<FileEntry> GetSharesForMeAsync(FilterType filterType, bool subjectGroup, Guid subjectID, string searchText = "", bool searchInContent = false, bool withSubfolders = false)
|
||||
{
|
||||
var securityDao = _daoFactory.GetSecurityDao<int>();
|
||||
|
@ -30,7 +30,7 @@ namespace ASC.Files.Core.Security;
|
||||
public interface ISecurityDao<T>
|
||||
{
|
||||
Task SetShareAsync(FileShareRecord r);
|
||||
IAsyncEnumerable<FileShareRecord> GetShareForEntryIdsAsync(Guid subject, IEnumerable<string> roomIds);
|
||||
IAsyncEnumerable<FileShareRecord> GetShareForEntryIdsAsync(Guid subject, IEnumerable<string> roomIds);
|
||||
IAsyncEnumerable<FileShareRecord> GetSharesAsync(IEnumerable<Guid> subjects);
|
||||
Task<IEnumerable<FileShareRecord>> GetSharesAsync(FileEntry<T> entry);
|
||||
Task RemoveSubjectAsync(Guid subject);
|
||||
@ -38,4 +38,5 @@ public interface ISecurityDao<T>
|
||||
IAsyncEnumerable<FileShareRecord> GetPureShareRecordsAsync(FileEntry<T> entry);
|
||||
Task DeleteShareRecordsAsync(IEnumerable<FileShareRecord> records);
|
||||
Task<bool> IsSharedAsync(T entryId, FileEntryType type);
|
||||
}
|
||||
IAsyncEnumerable<FileShareRecord> GetRoomSharesAsync(Folder<T> room, ShareFilterType filterType, int offset, int count);
|
||||
}
|
||||
|
@ -464,6 +464,68 @@ public class FileSharing
|
||||
return await _fileSharingHelper.CanSetAccessAsync(entry);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<AceWrapper> GetRoomSharedInfoAsync<T>(Folder<T> room, ShareFilterType filterType, int offset, int count)
|
||||
{
|
||||
if (room == null || !DocSpaceHelper.IsRoom(room.FolderType))
|
||||
{
|
||||
throw new ArgumentNullException(FilesCommonResource.ErrorMassage_BadRequest);
|
||||
}
|
||||
|
||||
if (!await _fileSecurity.CanReadAsync(room))
|
||||
{
|
||||
_logger.ErrorUserCanTGetSharedInfo(_authContext.CurrentAccount.ID, room.FileEntryType, room.Id.ToString()!);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
var canEditAccess = await _fileSecurity.CanEditAccessAsync(room);
|
||||
|
||||
var defaultAces = await GetDefaultRoomAcesAsync(room, filterType).Skip(offset).Take(count).ToListAsync();
|
||||
|
||||
offset = offset == 0 ? offset : offset - defaultAces.Count;
|
||||
count -= defaultAces.Count;
|
||||
|
||||
var records = _fileSecurity.GetRoomSharesAsync(room, filterType, offset, count);
|
||||
|
||||
foreach (var record in defaultAces)
|
||||
{
|
||||
yield return record;
|
||||
}
|
||||
|
||||
await foreach (var record in records)
|
||||
{
|
||||
var w = new AceWrapper
|
||||
{
|
||||
Id = record.Subject,
|
||||
SubjectGroup = false,
|
||||
Access = record.Share,
|
||||
FileShareOptions = record.FileShareOptions,
|
||||
SubjectType = record.SubjectType
|
||||
};
|
||||
|
||||
w.CanEditAccess = _authContext.CurrentAccount.ID != w.Id && w.SubjectType == SubjectType.UserOrGroup && canEditAccess;
|
||||
|
||||
if (record.IsLink)
|
||||
{
|
||||
w.Link = _invitationLinkService.GetInvitationLink(record.Subject, _authContext.CurrentAccount.ID);
|
||||
w.SubjectGroup = true;
|
||||
w.CanEditAccess = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = await _userManager.GetUsersAsync(record.Subject);
|
||||
|
||||
w.SubjectName = user.DisplayUserName(false, _displayUserSettingsHelper);
|
||||
w.Owner = room.RootFolderType == FolderType.USER
|
||||
? room.RootCreateBy == record.Subject
|
||||
: room.CreateBy == record.Subject;
|
||||
w.LockedRights = record.Subject == _authContext.CurrentAccount.ID;
|
||||
}
|
||||
|
||||
yield return w;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<AceWrapper>> GetSharedInfoAsync<T>(FileEntry<T> entry)
|
||||
{
|
||||
if (entry == null)
|
||||
@ -791,4 +853,41 @@ public class FileSharing
|
||||
.Where(aceWrapper => !aceWrapper.Id.Equals(FileConstant.ShareLinkId) || aceWrapper.Access != FileShare.Restrict)
|
||||
.Select(aceWrapper => new AceShortWrapper(aceWrapper)));
|
||||
}
|
||||
|
||||
private async IAsyncEnumerable<AceWrapper> GetDefaultRoomAcesAsync<T>(Folder<T> room, ShareFilterType filterType)
|
||||
{
|
||||
switch (filterType)
|
||||
{
|
||||
case ShareFilterType.InvitationLink or ShareFilterType.Link:
|
||||
{
|
||||
var id = Guid.NewGuid();
|
||||
var w = new AceWrapper
|
||||
{
|
||||
Id = id,
|
||||
Link = _invitationLinkService.GetInvitationLink(id, _authContext.CurrentAccount.ID),
|
||||
SubjectGroup = true,
|
||||
Access = FileShare.Read,
|
||||
Owner = false
|
||||
};
|
||||
|
||||
yield return w;
|
||||
break;
|
||||
}
|
||||
case ShareFilterType.User:
|
||||
{
|
||||
var w = new AceWrapper
|
||||
{
|
||||
Id = room.CreateBy,
|
||||
SubjectName = await _global.GetUserNameAsync(room.CreateBy),
|
||||
SubjectGroup = false,
|
||||
Access = FileShare.ReadWrite,
|
||||
Owner = true,
|
||||
CanEditAccess = false,
|
||||
};
|
||||
|
||||
yield return w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -40,7 +40,8 @@ public class VirtualRoomsInternalController : VirtualRoomsController<int>
|
||||
FileDtoHelper fileDtoHelper,
|
||||
FileShareDtoHelper fileShareDtoHelper,
|
||||
IMapper mapper,
|
||||
SocketManager socketManager) : base(
|
||||
SocketManager socketManager,
|
||||
ApiContext apiContext) : base(
|
||||
globalFolderHelper,
|
||||
fileOperationDtoHelper,
|
||||
coreBaseSettings,
|
||||
@ -51,7 +52,8 @@ public class VirtualRoomsInternalController : VirtualRoomsController<int>
|
||||
fileDtoHelper,
|
||||
fileShareDtoHelper,
|
||||
mapper,
|
||||
socketManager)
|
||||
socketManager,
|
||||
apiContext)
|
||||
{
|
||||
}
|
||||
|
||||
@ -94,7 +96,8 @@ public class VirtualRoomsThirdPartyController : VirtualRoomsController<string>
|
||||
FileDtoHelper fileDtoHelper,
|
||||
FileShareDtoHelper fileShareDtoHelper,
|
||||
IMapper mapper,
|
||||
SocketManager socketManager) : base(
|
||||
SocketManager socketManager,
|
||||
ApiContext apiContext) : base(
|
||||
globalFolderHelper,
|
||||
fileOperationDtoHelper,
|
||||
coreBaseSettings,
|
||||
@ -105,7 +108,8 @@ public class VirtualRoomsThirdPartyController : VirtualRoomsController<string>
|
||||
fileDtoHelper,
|
||||
fileShareDtoHelper,
|
||||
mapper,
|
||||
socketManager)
|
||||
socketManager,
|
||||
apiContext)
|
||||
{
|
||||
}
|
||||
|
||||
@ -149,6 +153,7 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
|
||||
private readonly FileShareDtoHelper _fileShareDtoHelper;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly SocketManager _socketManager;
|
||||
private readonly ApiContext _apiContext;
|
||||
|
||||
protected VirtualRoomsController(
|
||||
GlobalFolderHelper globalFolderHelper,
|
||||
@ -161,7 +166,8 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
|
||||
FileDtoHelper fileDtoHelper,
|
||||
FileShareDtoHelper fileShareDtoHelper,
|
||||
IMapper mapper,
|
||||
SocketManager socketManager) : base(folderDtoHelper, fileDtoHelper)
|
||||
SocketManager socketManager,
|
||||
ApiContext apiContext) : base(folderDtoHelper, fileDtoHelper)
|
||||
{
|
||||
_globalFolderHelper = globalFolderHelper;
|
||||
_fileOperationDtoHelper = fileOperationDtoHelper;
|
||||
@ -172,6 +178,7 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
|
||||
_fileShareDtoHelper = fileShareDtoHelper;
|
||||
_mapper = mapper;
|
||||
_socketManager = socketManager;
|
||||
_apiContext = apiContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -356,16 +363,33 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
|
||||
/// <param name="id">
|
||||
/// Room ID
|
||||
/// </param>
|
||||
/// <param name="filterType">
|
||||
/// Share type filter
|
||||
/// </param>
|
||||
/// <returns>Room security info</returns>
|
||||
[HttpGet("rooms/{id}/share")]
|
||||
public async IAsyncEnumerable<FileShareDto> GetRoomSecurityInfoAsync(T id)
|
||||
public async IAsyncEnumerable<FileShareDto> GetRoomSecurityInfoAsync(T id, ShareFilterType filterType = ShareFilterType.User)
|
||||
{
|
||||
var fileShares = await _fileStorageService.GetSharedInfoAsync(Array.Empty<T>(), new[] { id });
|
||||
const int margin = 1;
|
||||
|
||||
var offset = Convert.ToInt32(_apiContext.StartIndex);
|
||||
var count = Convert.ToInt32(_apiContext.Count);
|
||||
var counter = 0;
|
||||
|
||||
foreach (var fileShareDto in fileShares)
|
||||
await foreach (var ace in _fileStorageService.GetRoomSharedInfoAsync(id, filterType, offset, count + margin))
|
||||
{
|
||||
yield return await _fileShareDtoHelper.Get(fileShareDto);
|
||||
counter++;
|
||||
|
||||
if (counter > count)
|
||||
{
|
||||
_apiContext.Next = true;
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return await _fileShareDtoHelper.Get(ace);
|
||||
}
|
||||
|
||||
_apiContext.Next = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user