Merge pull request #780 from ONLYOFFICE/feature/private-virtual-rooms

Feature/private virtual rooms
This commit is contained in:
Alexey Bannov 2022-09-01 19:34:12 +04:00 committed by GitHub
commit 7895a214c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 5874 additions and 209 deletions

View File

@ -98,6 +98,11 @@ public class AccountLinker
return GetLinkedProfiles(obj).Where(profile => profile.Provider.Equals(provider));
}
public IDictionary<string, LoginProfile> GetLinkedProfiles(IEnumerable<string> objects, string provider)
{
return GetLinkedProfiles(objects).Where(o => o.Value.Provider.Equals(provider)).ToDictionary(k => k.Key, v => v.Value);
}
public IEnumerable<LoginProfile> GetLinkedProfiles(string obj)
{
return _accountLinkerStorage.GetFromCache(obj, GetLinkedProfilesFromDB);
@ -182,4 +187,13 @@ public class AccountLinker
.ToList()
.ConvertAll(x => LoginProfile.CreateFromSerializedString(_signature, _instanceCrypto, x));
}
private IDictionary<string, LoginProfile> GetLinkedProfiles(IEnumerable<string> objects)
{
using var accountLinkContext = _accountLinkContextManager.CreateDbContext();
return accountLinkContext.AccountLinks.Where(r => objects.Contains(r.Id))
.Select(r => new { r.Id, r.Profile })
.ToDictionary(k => k.Id, v => LoginProfile.CreateFromSerializedString(_signature, _instanceCrypto, v.Profile));
}
}

View File

@ -90,4 +90,28 @@ public class EncryptionLoginProvider
return null;
}
}
public IDictionary<Guid, string> GetKeys(IEnumerable<Guid> usrsIds)
{
var profiles = _accountLinker.GetLinkedProfiles(usrsIds.Select(id => id.ToString()), ProviderConstants.Encryption);
var keys = new Dictionary<Guid, string>(profiles.Count);
foreach (var profilePair in profiles)
{
var userId = new Guid(profilePair.Key);
try
{
var key = _instanceCrypto.Decrypt(profilePair.Value.Name);
keys.Add(new Guid(profilePair.Key), key);
}
catch (Exception ex)
{
var message = string.Format("Can not decrypt {0} keys for {1}", ProviderConstants.Encryption, userId);
_logger.ErrorWithException(message, ex);
}
}
return keys;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.FilesDb
{
public partial class FilesDbContext_Upgrade1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "private",
table: "files_thirdparty_account",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "private",
table: "files_folder",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "private",
table: "files_thirdparty_account");
migrationBuilder.DropColumn(
name: "private",
table: "files_folder");
}
}
}

View File

@ -16,7 +16,7 @@ namespace ASC.Migrations.MySql.Migrations.FilesDb
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
@ -2451,6 +2451,10 @@ namespace ASC.Migrations.MySql.Migrations.FilesDb
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool>("Private")
.HasColumnType("tinyint(1)")
.HasColumnName("private");
b.Property<string>("Provider")
.IsRequired()
.ValueGeneratedOnAdd()
@ -2630,6 +2634,10 @@ namespace ASC.Migrations.MySql.Migrations.FilesDb
.HasColumnName("parent_id")
.HasDefaultValueSql("'0'");
b.Property<bool>("Private")
.HasColumnType("tinyint(1)")
.HasColumnName("private");
b.Property<int>("TenantId")
.HasColumnType("int")
.HasColumnName("tenant_id");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.FilesDb
{
public partial class FilesDbContext_Upgrade1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "FolderId",
schema: "onlyoffice",
table: "files_thirdparty_account",
newName: "folder_id");
migrationBuilder.AddColumn<bool>(
name: "private",
schema: "onlyoffice",
table: "files_thirdparty_account",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "private",
schema: "onlyoffice",
table: "files_folder",
type: "boolean",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "private",
schema: "onlyoffice",
table: "files_thirdparty_account");
migrationBuilder.DropColumn(
name: "private",
schema: "onlyoffice",
table: "files_folder");
migrationBuilder.RenameColumn(
name: "folder_id",
schema: "onlyoffice",
table: "files_thirdparty_account",
newName: "FolderId");
}
}
}

View File

@ -18,7 +18,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
@ -2384,7 +2384,8 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnName("create_on");
b.Property<string>("FolderId")
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("folder_id");
b.Property<int>("FolderType")
.HasColumnType("integer")
@ -2396,6 +2397,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnType("character varying(100)")
.HasColumnName("password");
b.Property<bool>("Private")
.HasColumnType("boolean")
.HasColumnName("private");
b.Property<string>("Provider")
.IsRequired()
.ValueGeneratedOnAdd()
@ -2547,6 +2552,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnType("integer")
.HasColumnName("parent_id");
b.Property<bool>("Private")
.HasColumnType("boolean")
.HasColumnName("private");
b.Property<int>("TenantId")
.HasColumnType("integer")
.HasColumnName("tenant_id");

View File

@ -49,4 +49,8 @@ public class CreateRoomRequestDto
{
public string Title { get; set; }
public RoomType RoomType { get; set; }
public bool Private { get; set; }
public IEnumerable<FileShareParams> Share { get; set; }
public bool Notify { get; set; }
public string SharingMessage { get; set; }
}

View File

@ -38,6 +38,7 @@ public class FolderDto<T> : FileEntryDto<T>
public Logo Logo { get; set; }
public bool Pinned { get; set; }
public RoomType? RoomType { get; set; }
public bool Private { get; set; }
protected internal override FileEntryType EntryType { get => FileEntryType.Folder; }
@ -160,6 +161,7 @@ public class FolderDtoHelper : FileEntryDtoHelper
result.IsFavorite = folder.IsFavorite.NullIfDefault();
result.New = folder.NewForMe;
result.Pinned = folder.Pinned;
result.Private = folder.Private;
return result;
}

View File

@ -176,7 +176,7 @@ public interface IFolderDao<T>
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
bool UseTrashForRemove(Folder<T> folder);
bool UseTrashForRemoveAsync(Folder<T> folder);
/// <summary>
/// Check the need to use recursion for operations

View File

@ -35,7 +35,7 @@ public interface IProviderDao
IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(Guid userId);
Task<int> SaveProviderInfoAsync(string providerKey, string customerTitle, AuthData authData, FolderType folderType);
Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType);
Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType folderType);
Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType folderType, bool @private);
Task<int> UpdateProviderInfoAsync(int linkId, string customerTitle, AuthData authData, FolderType folderType, Guid? userId = null);
Task<int> UpdateBackupProviderInfoAsync(string providerKey, string customerTitle, AuthData authData);
Task RemoveProviderInfoAsync(int linkId);

View File

@ -37,6 +37,7 @@ public interface IProviderInfo : IDisposable
string CustomerTitle { get; }
string RootFolderId { get; }
string FolderId { get; set; }
bool Private { get; }
Task<bool> CheckAccessAsync();
Task InvalidateStorageAsync();

View File

@ -1079,9 +1079,14 @@ internal class FileDao : AbstractDao, IFileDao<int>
public bool UseTrashForRemove(File<int> file)
{
if (file.Encrypted && file.RootFolderType == FolderType.VirtualRooms)
{
return false;
}
return file.RootFolderType != FolderType.TRASH && file.RootFolderType != FolderType.Privacy;
}
public string GetUniqFileDirectory(int fileId)
{
if (fileId == 0)

View File

@ -448,6 +448,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
ModifiedOn = _tenantUtil.DateTimeToUtc(folder.ModifiedOn),
ModifiedBy = folder.ModifiedBy,
FolderType = folder.FolderType,
Private = folder.Private,
TenantId = TenantID
};
@ -889,9 +890,9 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
return await GetItemsCountAsync(folderId) == 0;
}
public bool UseTrashForRemove(Folder<int> folder)
public bool UseTrashForRemoveAsync(Folder<int> folder)
{
return folder.RootFolderType != FolderType.TRASH && folder.RootFolderType != FolderType.Privacy && folder.FolderType != FolderType.BUNCH;
return folder.RootFolderType != FolderType.TRASH && folder.RootFolderType != FolderType.Privacy && folder.FolderType != FolderType.BUNCH && folder.Private;
}
public bool UseRecursiveOperation(int folderId, string toRootFolderId)

View File

@ -41,6 +41,7 @@ public class DbFilesThirdpartyAccount : BaseEntity, IDbFile, IDbSearch
public string Url { get; set; }
public int TenantId { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
public override object[] GetKeys()
{
@ -63,10 +64,10 @@ public static class DbFilesThirdpartyAccountExtension
{
modelBuilder.Entity<DbFilesThirdpartyAccount>(entity =>
{
entity.ToTable("files_thirdparty_account")
.HasCharSet("utf8");
entity.HasIndex(e => e.TenantId).HasDatabaseName("tenant_id");
entity.ToTable("files_thirdparty_account")
.HasCharSet("utf8");
entity.HasIndex(e => e.TenantId).HasDatabaseName("tenant_id");
entity.Property(e => e.Id).HasColumnName("id");
@ -81,15 +82,15 @@ public static class DbFilesThirdpartyAccountExtension
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
entity.Property(e => e.FolderType)
.HasColumnName("folder_type")
.HasDefaultValueSql("'0'");
entity.Property(e => e.FolderType)
.HasColumnName("folder_type")
.HasDefaultValueSql("'0'");
entity.Property(e => e.RoomType).HasColumnName("room_type");
entity.Property(e => e.Password)
.IsRequired()
.HasColumnName("password")
.HasColumnType("varchar(512)")
.HasColumnType("varchar(512)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
@ -134,15 +135,17 @@ public static class DbFilesThirdpartyAccountExtension
.HasColumnType("text")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
entity.Property(e => e.Private).HasColumnName("private");
});
}
public static void PgSqlAddDbFilesThirdpartyAccount(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<DbFilesThirdpartyAccount>(entity =>
{
entity.ToTable("files_thirdparty_account", "onlyoffice");
entity.HasIndex(e => e.TenantId).HasDatabaseName("tenant_id");
entity.ToTable("files_thirdparty_account", "onlyoffice");
entity.HasIndex(e => e.TenantId).HasDatabaseName("tenant_id");
entity.Property(e => e.Id).HasColumnName("id");
@ -181,7 +184,11 @@ public static class DbFilesThirdpartyAccountExtension
entity.Property(e => e.UserName)
.IsRequired()
.HasColumnName("user_name")
.HasMaxLength(100);
.HasMaxLength(100);
entity.Property(e => e.FolderId).HasColumnName("folder_id");
entity.Property(e => e.Private).HasColumnName("private");
});
}
}

View File

@ -43,6 +43,7 @@ public class DbFolder : IDbFile, IDbSearch, ISearchItem
public int TenantId { get; set; }
public int FoldersCount { get; set; }
public int FilesCount { get; set; }
public bool Private { get; set; }
[Ignore]
public string IndexName => Tables.Folder;
@ -127,6 +128,8 @@ public static class DbFolderExtension
.HasColumnType("varchar(400)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
entity.Property(e => e.Private).HasColumnName("private");
});
}
public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder)
@ -173,6 +176,8 @@ public static class DbFolderExtension
.IsRequired()
.HasColumnName("title")
.HasMaxLength(400);
entity.Property(e => e.Private).HasColumnName("private");
});
}
}

View File

@ -103,6 +103,7 @@ public class EncryptionKeyPairDtoHelper
public async Task<IEnumerable<EncryptionKeyPairDto>> GetKeyPairAsync<T>(T fileId, FileStorageService<T> FileStorageService)
{
var fileDao = _daoFactory.GetFileDao<T>();
var folderDao = _daoFactory.GetFolderDao<T>();
await fileDao.InvalidateCacheAsync(fileId);
@ -117,7 +118,10 @@ public class EncryptionKeyPairDtoHelper
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile);
}
if (file.RootFolderType != FolderType.Privacy)
var locatedInPrivateRoom = file.RootFolderType == FolderType.VirtualRooms
&& await DocSpaceHelper.LocatedInPrivateRoomAsync(file, folderDao);
if (file.RootFolderType != FolderType.Privacy && !locatedInPrivateRoom)
{
throw new NotSupportedException();
}

View File

@ -74,6 +74,7 @@ public class Folder<T> : FileEntry<T>, IFolder
public int NewForMe { get; set; }
public string FolderUrl { get; set; }
public bool Pinned { get; set; }
public bool Private { get; set; }
public override bool IsNew
{
get => Convert.ToBoolean(NewForMe);

View File

@ -24,6 +24,7 @@
// 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 UrlShortener = ASC.Web.Core.Utility.UrlShortener;
namespace ASC.Web.Files.Services.WCFService;
@ -77,9 +78,10 @@ public class FileStorageService<T> //: IFileStorageService
private readonly TenantManager _tenantManager;
private readonly FileTrackerHelper _fileTracker;
private readonly IEventBus _eventBus;
private readonly EntryStatusManager _entryStatusManager;
private readonly ILogger _logger;
private readonly FileShareParamsHelper _fileShareParamsHelper;
private readonly EncryptionLoginProvider _encryptionLoginProvider;
public FileStorageService(
Global global,
@ -129,7 +131,9 @@ public class FileStorageService<T> //: IFileStorageService
MessageService messageService,
IServiceScopeFactory serviceScopeFactory,
ThirdPartySelector thirdPartySelector,
ThumbnailSettings thumbnailSettings)
ThumbnailSettings thumbnailSettings,
FileShareParamsHelper fileShareParamsHelper,
EncryptionLoginProvider encryptionLoginProvider)
{
_global = global;
_globalStore = globalStore;
@ -179,6 +183,8 @@ public class FileStorageService<T> //: IFileStorageService
_serviceScopeFactory = serviceScopeFactory;
_thirdPartySelector = thirdPartySelector;
_thumbnailSettings = thumbnailSettings;
_fileShareParamsHelper = fileShareParamsHelper;
_encryptionLoginProvider = encryptionLoginProvider;
}
public async Task<Folder<T>> GetFolderAsync(T folderId)
@ -443,31 +449,56 @@ public class FileStorageService<T> //: IFileStorageService
throw new ArgumentException();
}
return InternalCreateNewFolderAsync(parentId, title, FolderType.DEFAULT);
return InternalCreateNewFolderAsync(parentId, title);
}
public async Task<Folder<T>> CreateRoomAsync(string title, RoomType roomType)
public async Task<Folder<T>> CreateRoomAsync(string title, RoomType roomType, bool @private, IEnumerable<FileShareParams> share, bool notify, string sharingMessage)
{
ArgumentNullException.ThrowIfNull(title, nameof(title));
if (@private && (share == null || !share.Any()))
{
throw new ArgumentNullException(nameof(share));
}
List<AceWrapper> aces = null;
if (@private)
{
aces = GetFullAceWrappers(share);
CheckEncryptionKeys(aces);
}
var parentId = await _globalFolderHelper.GetFolderVirtualRooms<T>();
return roomType switch
var room = roomType switch
{
RoomType.CustomRoom => await CreateCustomRoomAsync(title, parentId),
RoomType.FillingFormsRoom => await CreateFillingFormsRoom(title, parentId),
RoomType.EditingRoom => await CreateEditingRoom(title, parentId),
RoomType.ReviewRoom => await CreateReviewRoom(title, parentId),
RoomType.ReadOnlyRoom => await CreateReadOnlyRoom(title, parentId),
_ => await CreateCustomRoomAsync(title, parentId),
RoomType.CustomRoom => await CreateCustomRoomAsync(title, parentId, @private),
RoomType.FillingFormsRoom => await CreateFillingFormsRoom(title, parentId, @private),
RoomType.EditingRoom => await CreateEditingRoom(title, parentId, @private),
RoomType.ReviewRoom => await CreateReviewRoom(title, parentId, @private),
RoomType.ReadOnlyRoom => await CreateReadOnlyRoom(title, parentId, @private),
_ => await CreateCustomRoomAsync(title, parentId, @private),
};
if (@private)
{
await SetAcesForPrivateRoomAsync(room, aces, notify, sharingMessage);
}
return room;
}
public async Task<Folder<T>> CreateThirdpartyRoomAsync(string title, RoomType roomType, T parentId)
public async Task<Folder<T>> CreateThirdPartyRoomAsync(string title, RoomType roomType, T parentId, bool @private, IEnumerable<FileShareParams> share, bool notify, string sharingMessage)
{
ArgumentNullException.ThrowIfNull(title, nameof(title));
ArgumentNullException.ThrowIfNull(parentId, nameof(parentId));
if (@private && (share == null || !share.Any()))
{
throw new ArgumentNullException(nameof(share));
}
var folderDao = GetFolderDao();
var providerDao = GetProviderDao();
@ -476,7 +507,7 @@ public class FileStorageService<T> //: IFileStorageService
if (providerInfo.RootFolderType != FolderType.VirtualRooms)
{
throw new InvalidOperationException("Invalid provider type");
throw new InvalidDataException("Invalid provider type");
}
if (providerInfo.FolderId != null)
@ -484,57 +515,60 @@ public class FileStorageService<T> //: IFileStorageService
throw new InvalidOperationException("This provider already corresponds to the virtual room");
}
var room = roomType switch
List<AceWrapper> aces = null;
if (@private)
{
RoomType.CustomRoom => await CreateCustomRoomAsync(title, parentId),
RoomType.FillingFormsRoom => await CreateFillingFormsRoom(title, parentId),
RoomType.EditingRoom => await CreateEditingRoom(title, parentId),
RoomType.ReviewRoom => await CreateReviewRoom(title, parentId),
RoomType.ReadOnlyRoom => await CreateReadOnlyRoom(title, parentId),
_ => await CreateCustomRoomAsync(title, parentId),
aces = GetFullAceWrappers(share);
CheckEncryptionKeys(aces);
}
var result = roomType switch
{
RoomType.CustomRoom => (await CreateCustomRoomAsync(title, parentId, @private), FolderType.CustomRoom),
RoomType.FillingFormsRoom => (await CreateFillingFormsRoom(title, parentId, @private), FolderType.FillingFormsRoom),
RoomType.EditingRoom => (await CreateEditingRoom(title, parentId, @private), FolderType.EditingRoom),
RoomType.ReviewRoom => (await CreateReviewRoom(title, parentId, @private), FolderType.ReviewRoom),
RoomType.ReadOnlyRoom => (await CreateReadOnlyRoom(title, parentId, @private), FolderType.ReadOnlyRoom),
_ => (await CreateCustomRoomAsync(title, parentId, @private), FolderType.CustomRoom),
};
var folderType = roomType switch
if (@private)
{
RoomType.CustomRoom => FolderType.CustomRoom,
RoomType.ReviewRoom => FolderType.ReviewRoom,
RoomType.EditingRoom => FolderType.EditingRoom,
RoomType.FillingFormsRoom => FolderType.FillingFormsRoom,
RoomType.ReadOnlyRoom => FolderType.ReadOnlyRoom,
_ => FolderType.CustomRoom
};
await SetAcesForPrivateRoomAsync(result.Item1, aces, notify, sharingMessage);
}
await providerDao.UpdateProviderInfoAsync(providerInfo.ID, room.Id.ToString(), folderType);
await providerDao.UpdateProviderInfoAsync(providerInfo.ID, result.Item1.Id.ToString(), result.Item2, @private);
return room;
return result.Item1;
}
private async Task<Folder<T>> CreateCustomRoomAsync(string title, T parentId)
private async Task<Folder<T>> CreateCustomRoomAsync(string title, T parentId, bool privacy)
{
return await InternalCreateNewFolderAsync(parentId, title, FolderType.CustomRoom);
return await InternalCreateNewFolderAsync(parentId, title, FolderType.CustomRoom, privacy);
}
private async Task<Folder<T>> CreateFillingFormsRoom(string title, T parentId)
private async Task<Folder<T>> CreateFillingFormsRoom(string title, T parentId, bool privacy)
{
return await InternalCreateNewFolderAsync(parentId, title, FolderType.FillingFormsRoom);
return await InternalCreateNewFolderAsync(parentId, title, FolderType.FillingFormsRoom, privacy);
}
private async Task<Folder<T>> CreateReviewRoom(string title, T parentId)
private async Task<Folder<T>> CreateReviewRoom(string title, T parentId, bool privacy)
{
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReviewRoom);
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReviewRoom, privacy);
}
private async Task<Folder<T>> CreateReadOnlyRoom(string title, T parentId)
private async Task<Folder<T>> CreateReadOnlyRoom(string title, T parentId, bool privacy)
{
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReadOnlyRoom);
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReadOnlyRoom, privacy);
}
private async Task<Folder<T>> CreateEditingRoom(string title, T parentId)
private async Task<Folder<T>> CreateEditingRoom(string title, T parentId, bool privacy)
{
return await InternalCreateNewFolderAsync(parentId, title, FolderType.EditingRoom);
return await InternalCreateNewFolderAsync(parentId, title, FolderType.EditingRoom, privacy);
}
public async Task<Folder<T>> InternalCreateNewFolderAsync(T parentId, string title, FolderType folderType = FolderType.DEFAULT)
public async Task<Folder<T>> InternalCreateNewFolderAsync(T parentId, string title, FolderType folderType = FolderType.DEFAULT, bool privacy = false)
{
var folderDao = GetFolderDao();
@ -553,6 +587,7 @@ public class FileStorageService<T> //: IFileStorageService
newFolder.Title = title;
newFolder.ParentId = parent.Id;
newFolder.FolderType = folderType;
newFolder.Private = parent.Private ? parent.Private : privacy;
var folderId = await folderDao.SaveFolderAsync(newFolder);
var folder = await folderDao.GetFolderAsync(folderId);
@ -1036,7 +1071,7 @@ public class FileStorageService<T> //: IFileStorageService
return _documentServiceHelper.GetDocKey(fileId, -1, DateTime.MinValue);
}
(File<string> File, Configuration<string> Configuration) fileOptions;
(File<string> File, Configuration<string> Configuration, bool LocatedInPrivateRoom) fileOptions;
app = _thirdPartySelector.GetAppByFileId(fileId.ToString());
if (app == null)
@ -2106,7 +2141,7 @@ public class FileStorageService<T> //: IFileStorageService
public async Task<string> CheckFillFormDraftAsync(T fileId, int version, string doc, bool editPossible, bool view)
{
var (file, _configuration) = await _documentServiceHelper.GetParamsAsync(fileId, version, doc, editPossible, !view, true);
var (file, _configuration, locatedInPrivateRoom) = await _documentServiceHelper.GetParamsAsync(fileId, version, doc, editPossible, !view, true);
var _valideShareLink = !string.IsNullOrEmpty(_fileShareLink.Parse(doc));
if (_valideShareLink)
@ -3108,6 +3143,61 @@ public class FileStorageService<T> //: IFileStorageService
return string.Empty;
}
}
private List<AceWrapper> GetFullAceWrappers(IEnumerable<FileShareParams> share)
{
var dict = new List<AceWrapper>(share.Select(_fileShareParamsHelper.ToAceObject)).ToDictionary(k => k.SubjectId, v => v);
var admins = _userManager.GetUsersByGroup(Constants.GroupAdmin.ID);
var onlyFilesAdmins = _userManager.GetUsersByGroup(WebItemManager.DocumentsProductID);
var userInfos = admins.Union(onlyFilesAdmins).ToList();
foreach (var userInfo in userInfos)
{
dict[userInfo.Id] = new AceWrapper
{
Share = FileShare.ReadWrite,
SubjectId = userInfo.Id
};
}
return dict.Values.ToList();
}
private void CheckEncryptionKeys(IEnumerable<AceWrapper> aceWrappers)
{
var users = aceWrappers.Select(s => s.SubjectId).ToList();
var keys = _encryptionLoginProvider.GetKeys(users);
foreach (var user in users)
{
if (!keys.ContainsKey(user))
{
var userInfo = _userManager.GetUsers(user);
throw new InvalidOperationException($"The user {userInfo.DisplayUserName(_displayUserSettingsHelper)} does not have an encryption key");
}
}
}
private async Task SetAcesForPrivateRoomAsync(Folder<T> room, List<AceWrapper> aces, bool notify, string sharingMessage)
{
var advancedSettings = new AceAdvancedSettingsWrapper
{
AllowSharingPrivateRoom = true
};
var aceCollection = new AceCollection<T>
{
Folders = new[] { room.Id },
Files = Array.Empty<T>(),
Aces = aces,
Message = sharingMessage,
AdvancedSettings = advancedSettings
};
await SetAceObjectAsync(aceCollection, notify);
}
}
public class FileModel<T, TTempate>

View File

@ -1037,7 +1037,7 @@ public class FileSecurity : IFileSecurity
foreach (var record in recordGroup.Where(r => r.firstRecord.Share != FileShare.Restrict))
{
if (!roomsIds.ContainsKey((T)record.firstRecord.EntryId))
if (!roomsIds.ContainsKey((T)record.firstRecord.EntryId) && record.firstRecord.EntryType == FileEntryType.Folder)
{
roomsIds.Add((T)record.firstRecord.EntryId, record.firstRecord.Share);
}

View File

@ -123,6 +123,7 @@ internal abstract class BoxDaoBase : ThirdPartyProviderDao<BoxProviderInfo>
folder.Title = MakeFolderTitle(boxFolder);
folder.FilesCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFile) : 0;
folder.FoldersCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFolder) : 0;
folder.Private = ProviderInfo.Private;
SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
@ -194,6 +195,7 @@ internal abstract class BoxDaoBase : ThirdPartyProviderDao<BoxProviderInfo>
file.NativeAccessor = boxFile;
file.Title = MakeFileTitle(boxFile);
file.ThumbnailStatus = Thumbnail.Created;
file.Encrypted = ProviderInfo.Private;
return file;
}

View File

@ -497,7 +497,7 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao<string>
return items.Count == 0;
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -56,6 +56,7 @@ internal class BoxProviderInfo : IProviderInfo
public FolderType RootFolderType { get; set; }
public FolderType FolderType { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
public string BoxRootId
{
@ -161,11 +162,11 @@ internal class BoxStorageDisposableWrapper : IDisposable
public BoxStorage Storage { get; private set; }
private readonly OAuth20TokenHelper _oAuth20TokenHelper;
private readonly ConsumerFactory _consumerFactory;
private readonly TempStream _tempStream;
private readonly IServiceProvider _serviceProvider;
public BoxStorageDisposableWrapper(ConsumerFactory consumerFactory, TempStream tempStream, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
private readonly ConsumerFactory _consumerFactory;
private readonly TempStream _tempStream;
private readonly IServiceProvider _serviceProvider;
public BoxStorageDisposableWrapper(ConsumerFactory consumerFactory, TempStream tempStream, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
{
_consumerFactory = consumerFactory;
_tempStream = tempStream;
@ -207,7 +208,7 @@ internal class BoxStorageDisposableWrapper : IDisposable
{
if (token.IsExpired)
{
token = _oAuth20TokenHelper.RefreshToken<BoxLoginProvider>(_consumerFactory, token);
token = _oAuth20TokenHelper.RefreshToken<BoxLoginProvider>(_consumerFactory, token);
var dbDao = _serviceProvider.GetService<ProviderAccountDao>();
await dbDao.UpdateProviderInfoAsync(id, new AuthData(token: token.ToJson()));
@ -343,4 +344,4 @@ public class BoxProviderInfoHelper
{
return await storage.GetThumbnailAsync(boxFileId, width, height);
}
}
}

View File

@ -127,6 +127,7 @@ internal abstract class DropboxDaoBase : ThirdPartyProviderDao<DropboxProviderIn
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : default;
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : default;
folder.Title = MakeFolderTitle(dropboxFolder);
folder.Private = ProviderInfo.Private;
SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
@ -198,6 +199,7 @@ internal abstract class DropboxDaoBase : ThirdPartyProviderDao<DropboxProviderIn
file.NativeAccessor = dropboxFile;
file.Title = MakeFileTitle(dropboxFile);
file.ThumbnailStatus = Thumbnail.Created;
file.Encrypted = ProviderInfo.Private;
return file;
}

View File

@ -490,7 +490,7 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao<string>
return items.Count == 0;
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -55,6 +55,7 @@ internal class DropboxProviderInfo : IProviderInfo
public FolderType RootFolderType { get; set; }
public FolderType FolderType { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
private readonly DropboxStorageDisposableWrapper _wrapper;
private readonly DropboxProviderInfoHelper _dropboxProviderInfoHelper;
@ -322,7 +323,7 @@ public class DropboxProviderInfoHelper
{
return storage.GetThumbnailsAsync(filePath, width, height);
}
}
}
public static class DropboxStorageDisposableWrapperExtention
{

View File

@ -139,6 +139,7 @@ internal abstract class GoogleDriveDaoBase : ThirdPartyProviderDao<GoogleDrivePr
folder.ParentId = isRoot ? null : MakeId(GetParentDriveId(driveEntry));
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.CreatedTime ?? default);
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.ModifiedTime ?? default);
folder.Private = ProviderInfo.Private;
SetFolderType(folder, isRoot);
folder.Title = MakeFolderTitle(driveEntry);
@ -217,6 +218,7 @@ internal abstract class GoogleDriveDaoBase : ThirdPartyProviderDao<GoogleDrivePr
file.NativeAccessor = driveFile;
file.Title = MakeFileTitle(driveFile);
file.ThumbnailStatus = Thumbnail.Created;
file.Encrypted = ProviderInfo.Private;
return file;
}

View File

@ -490,7 +490,7 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao<string>
return entries.Count == 0;
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -23,9 +23,9 @@
// 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 DriveFile = Google.Apis.Drive.v3.Data.File;
using DriveFile = Google.Apis.Drive.v3.Data.File;
namespace ASC.Files.Thirdparty.GoogleDrive;
[Transient]
@ -59,6 +59,7 @@ internal class GoogleDriveProviderInfo : IProviderInfo
public FolderType RootFolderType { get; set; }
public FolderType FolderType { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
public string DriveRootId
{
get
@ -175,7 +176,7 @@ internal class GoogleDriveStorageDisposableWrapper : IDisposable
private readonly ConsumerFactory _consumerFactory;
private readonly IServiceProvider _serviceProvider;
public GoogleDriveStorageDisposableWrapper(ConsumerFactory consumerFactory, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
public GoogleDriveStorageDisposableWrapper(ConsumerFactory consumerFactory, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
{
_consumerFactory = consumerFactory;
_serviceProvider = serviceProvider;
@ -217,7 +218,7 @@ internal class GoogleDriveStorageDisposableWrapper : IDisposable
{
if (token.IsExpired)
{
token = _oAuth20TokenHelper.RefreshToken<GoogleLoginProvider>(_consumerFactory, token);
token = _oAuth20TokenHelper.RefreshToken<GoogleLoginProvider>(_consumerFactory, token);
var dbDao = _serviceProvider.GetService<ProviderAccountDao>();
var authData = new AuthData(token: token.ToJson());
@ -390,4 +391,4 @@ public static class GoogleDriveProviderInfoExtention
{
dIHelper.TryAdd<GoogleDriveStorage>();
}
}
}

View File

@ -466,7 +466,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
return filterType is FilterType.FilesOnly or FilterType.ByExtension or FilterType.DocumentsOnly or FilterType.ImagesOnly or FilterType.PresentationsOnly
or FilterType.SpreadsheetsOnly or FilterType.ArchiveOnly or FilterType.MediaOnly;
}
protected abstract string MakeId(string path = null);
@ -662,7 +662,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
tags.Add(new Tag
{
Name = r.tag.Name,
Type = r.tag.Type,
Type = r.tag.Type,
Owner = r.tag.Owner,
EntryId = await MappingIDAsync(r.tagLink.EntryId),
EntryType = r.tagLink.EntryType,
@ -677,7 +677,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
foreach (var e in tags)
{
yield return e;
}
}
yield break;
}

View File

@ -126,6 +126,7 @@ internal abstract class OneDriveDaoBase : ThirdPartyProviderDao<OneDriveProvider
folder.ParentId = isRoot ? null : MakeId(GetParentFolderId(onedriveFolder));
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.CreatedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.CreatedDateTime.Value.DateTime) : default);
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.LastModifiedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.LastModifiedDateTime.Value.DateTime) : default);
folder.Private = ProviderInfo.Private;
SetFolderType(folder, isRoot);
folder.Title = MakeItemTitle(onedriveFolder);
@ -194,6 +195,7 @@ internal abstract class OneDriveDaoBase : ThirdPartyProviderDao<OneDriveProvider
file.NativeAccessor = onedriveFile;
file.Title = MakeItemTitle(onedriveFile);
file.ThumbnailStatus = Thumbnail.Created;
file.Encrypted = ProviderInfo.Private;
return file;
}

View File

@ -502,7 +502,7 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao<string>
|| onedriveFolder.Folder.ChildCount == 0;
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -23,7 +23,7 @@
// 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.Thirdparty.OneDrive;
[Transient]
@ -56,6 +56,7 @@ internal class OneDriveProviderInfo : IProviderInfo
public FolderType RootFolderType { get; set; }
public FolderType FolderType { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
private readonly OneDriveStorageDisposableWrapper _wrapper;
private readonly OneDriveProviderInfoHelper _oneDriveProviderInfoHelper;
@ -140,7 +141,7 @@ internal class OneDriveStorageDisposableWrapper : IDisposable
internal readonly ConsumerFactory ConsumerFactory;
internal readonly IServiceProvider ServiceProvider;
public OneDriveStorageDisposableWrapper(ConsumerFactory consumerFactory, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
public OneDriveStorageDisposableWrapper(ConsumerFactory consumerFactory, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper)
{
ConsumerFactory = consumerFactory;
ServiceProvider = serviceProvider;
@ -182,7 +183,7 @@ internal class OneDriveStorageDisposableWrapper : IDisposable
{
if (token.IsExpired)
{
token = _oAuth20TokenHelper.RefreshToken<OneDriveLoginProvider>(ConsumerFactory, token);
token = _oAuth20TokenHelper.RefreshToken<OneDriveLoginProvider>(ConsumerFactory, token);
var dbDao = ServiceProvider.GetService<ProviderAccountDao>();
var authData = new AuthData(token: token.ToJson());
@ -302,4 +303,4 @@ public static class OneDriveProviderInfoExtention
{
dIHelper.TryAdd<OneDriveStorage>();
}
}
}

View File

@ -207,7 +207,7 @@ internal class ProviderAccountDao : IProviderDao
{
return providerInfo != null && await providerInfo.CheckAccessAsync();
}
public async Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType)
{
using var filesDbContext = _dbContextFactory.CreateDbContext();
@ -229,7 +229,7 @@ internal class ProviderAccountDao : IProviderDao
return true;
}
public async Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType roomType)
public async Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType roomType, bool @private)
{
using var filesDbContext = _dbContextFactory.CreateDbContext();
var forUpdate = await filesDbContext.ThirdpartyAccount
@ -245,6 +245,7 @@ internal class ProviderAccountDao : IProviderDao
forUpdate.RoomType = roomType;
forUpdate.FolderId = folderId;
forUpdate.FolderType = FolderType.VirtualRooms;
forUpdate.Private = @private;
await filesDbContext.SaveChangesAsync();
@ -491,6 +492,7 @@ internal class ProviderAccountDao : IProviderDao
var owner = input.UserId;
var rootFolderType = input.FolderType;
var folderType = input.RoomType;
var privateRoom = input.Private;
var folderId = input.FolderId;
var createOn = _tenantUtil.DateTimeFromUtc(input.CreateOn);
var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password, id), token);
@ -512,6 +514,7 @@ internal class ProviderAccountDao : IProviderDao
box.Token = OAuth20Token.FromJson(token);
box.FolderType = folderType;
box.FolderId = folderId;
box.Private = privateRoom;
return box;
}
@ -533,6 +536,7 @@ internal class ProviderAccountDao : IProviderDao
drop.Token = OAuth20Token.FromJson(token);
drop.FolderType = folderType;
drop.FolderId = folderId;
drop.Private = privateRoom;
return drop;
}
@ -554,6 +558,7 @@ internal class ProviderAccountDao : IProviderDao
sh.InitClientContext(authData);
sh.FolderType = folderType;
sh.FolderId = folderId;
sh.Private = privateRoom;
return sh;
}
@ -575,6 +580,7 @@ internal class ProviderAccountDao : IProviderDao
gd.Token = OAuth20Token.FromJson(token);
gd.FolderType = folderType;
gd.FolderId = folderId;
gd.Private = privateRoom;
return gd;
}
@ -596,6 +602,7 @@ internal class ProviderAccountDao : IProviderDao
od.Token = OAuth20Token.FromJson(token);
od.FolderType = folderType;
od.FolderId = folderId;
od.Private = privateRoom;
return od;
}
@ -625,6 +632,7 @@ internal class ProviderAccountDao : IProviderDao
sharpBoxProviderInfo.AuthData = authData;
sharpBoxProviderInfo.FolderType = folderType;
sharpBoxProviderInfo.FolderId = folderId;
sharpBoxProviderInfo.Private = privateRoom;
return sharpBoxProviderInfo;
}

View File

@ -57,11 +57,11 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
private async Task<Folder<string>> InternalGetFolderAsync(string folderId, IDaoSelector selector)
{
var folderDao = selector.GetFolderDao(folderId);
var result = await folderDao.GetFolderAsync(selector.ConvertId(folderId));
var result = await folderDao.GetFolderAsync(selector.ConvertId(folderId));
if (result != null)
{
await SetSharedPropertyAsync(new[] { result });
await SetSharedPropertyAsync(new[] { result });
}
return result;
@ -114,10 +114,10 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
var selectorLocal = selector;
var matchedIds = roomsIds.Where(selectorLocal.IsMatch).ToList();
if (matchedIds.Count == 0)
{
continue;
}
if (matchedIds.Count == 0)
{
continue;
}
result = result.Concat(matchedIds.GroupBy(selectorLocal.GetIdCode)
.ToAsyncEnumerable()
@ -166,10 +166,10 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
var selectorLocal = selector;
var matchedIds = folderIds.Where(selectorLocal.IsMatch).ToList();
if (matchedIds.Count == 0)
{
continue;
}
if (matchedIds.Count == 0)
{
continue;
}
result = result.Concat(matchedIds.GroupBy(selectorLocal.GetIdCode)
.ToAsyncEnumerable()
@ -327,18 +327,18 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
public Task<IDictionary<string, string>> CanMoveOrCopyAsync(string[] folderIds, string to)
{
if (folderIds.Length == 0)
{
return Task.FromResult<IDictionary<string, string>>(new Dictionary<string, string>());
}
if (folderIds.Length == 0)
{
return Task.FromResult<IDictionary<string, string>>(new Dictionary<string, string>());
}
var selector = GetSelector(to);
var matchedIds = folderIds.Where(selector.IsMatch).ToArray();
if (matchedIds.Length == 0)
{
return Task.FromResult<IDictionary<string, string>>(new Dictionary<string, string>());
}
if (matchedIds.Length == 0)
{
return Task.FromResult<IDictionary<string, string>>(new Dictionary<string, string>());
}
return InternalCanMoveOrCopyAsync(to, matchedIds, selector);
}
@ -377,12 +377,12 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
return folderDao.IsEmptyAsync(selector.ConvertId(folderId));
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
var selector = GetSelector(folder.Id);
var folderDao = selector.GetFolderDao(folder.Id);
return folderDao.UseTrashForRemove(folder);
return folderDao.UseTrashForRemoveAsync(folder);
}
public bool UseRecursiveOperation<TTo>(string folderId, TTo toRootFolderId)
@ -435,4 +435,4 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
return storageMaxUploadSize;
}
}
}

View File

@ -156,7 +156,7 @@ internal abstract class RegexDaoSelectorBase<T> : IDaoSelector<T> where T : clas
public async Task UpdateProviderFolderId(T provider, string id)
{
var dbDao = _serviceProvider.GetService<ProviderAccountDao>();
await dbDao.UpdateProviderInfoAsync(provider.ID, id, provider.FolderType);
await dbDao.UpdateProviderInfoAsync(provider.ID, id, provider.FolderType, provider.Private);
provider.FolderId = id;
}

View File

@ -428,7 +428,7 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao<string>
return folder.ItemCount == 0;
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -44,6 +44,7 @@ public class SharePointProviderInfo : IProviderInfo
public string RootFolderId => "spoint-" + ID;
public string SpRootFolderId { get; set; } = "/Shared Documents";
public string FolderId { get; set; }
public bool Private { get; set; }
public SharePointProviderInfo(
ILogger<SharePointProviderInfo> logger,
@ -303,6 +304,7 @@ public class SharePointProviderInfo : IProviderInfo
result.RootFolderType = RootFolderType;
result.Title = MakeTitle(GetTitleById(errorFile.ID));
result.Error = errorFile.Error;
result.Encrypted = Private;
return result;
}
@ -324,6 +326,7 @@ public class SharePointProviderInfo : IProviderInfo
result.RootCreateBy = Owner;
result.Shared = false;
result.Version = 1;
result.Encrypted = Private;
if (file.IsPropertyAvailable("Length"))
{
@ -572,6 +575,7 @@ public class SharePointProviderInfo : IProviderInfo
result.FilesCount = 0;
result.FoldersCount = 0;
result.Error = errorFolder.Error;
result.Private = Private;
return result;
}
@ -594,6 +598,7 @@ public class SharePointProviderInfo : IProviderInfo
result.Title = isRoot ? CustomerTitle : MakeTitle(folder.Name);
result.FilesCount = 0;
result.FoldersCount = 0;
result.Private = Private;
SetFolderType(result, isRoot);

View File

@ -309,6 +309,7 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao<SharpBoxProvider
folder.Title = MakeTitle(fsEntry);
folder.FilesCount = 0; /*fsEntry.Count - childFoldersCount NOTE: Removed due to performance isssues*/
folder.FoldersCount = 0; /*childFoldersCount NOTE: Removed due to performance isssues*/
folder.Private = ProviderInfo.Private;
SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
@ -394,6 +395,7 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao<SharpBoxProvider
file.NativeAccessor = fsEntry;
file.Title = MakeTitle(fsEntry);
file.RootId = RootFolderMakeId();
file.Encrypted = ProviderInfo.Private;
return file;
}

View File

@ -484,7 +484,7 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao<string>
return Task.FromResult(GetFolderById(folderId).Count == 0);
}
public bool UseTrashForRemove(Folder<string> folder)
public bool UseTrashForRemoveAsync(Folder<string> folder)
{
return false;
}

View File

@ -111,6 +111,7 @@ internal class SharpBoxProviderInfo : IProviderInfo
public FolderType RootFolderType { get; set; }
public FolderType FolderType { get; set; }
public string FolderId { get; set; }
public bool Private { get; set; }
private readonly SharpBoxStorageDisposableWrapper _wrapper;
}
@ -161,4 +162,4 @@ class SharpBoxStorageDisposableWrapper : IDisposable
Storage = null;
}
}
}
}

View File

@ -87,7 +87,8 @@ global using ASC.FederatedLogin;
global using ASC.FederatedLogin.Helpers;
global using ASC.FederatedLogin.LoginProviders;
global using ASC.FederatedLogin.Profile;
global using ASC.Files.Core;
global using ASC.Files.Core;
global using ASC.Files.Core.ApiModels;
global using ASC.Files.Core.ApiModels.RequestDto;
global using ASC.Files.Core.ApiModels.ResponseDto;
global using ASC.Files.Core.Core.Entries;

View File

@ -44,6 +44,14 @@ public static class DocSpaceHelper
|| folderType == FolderType.FillingFormsRoom;
}
public static async Task<bool> LocatedInPrivateRoomAsync<T>(File<T> file, IFolderDao<T> folderDao)
{
var parents = await folderDao.GetParentFoldersAsync(file.ParentId).ToListAsync();
var room = parents.FirstOrDefault(f => IsRoom(f.FolderType));
return room != null && room.Private;
}
public static bool ValidateShare(FolderType folderType, FileShare fileShare)
{
return folderType switch

View File

@ -76,7 +76,7 @@ public class DocumentServiceHelper
_serviceProvider = serviceProvider;
}
public async Task<(File<T> File, Configuration<T> Configuration)> GetParamsAsync<T>(T fileId, int version, string doc, bool editPossible, bool tryEdit, bool tryCoauth)
public async Task<(File<T> File, Configuration<T> Configuration, bool LocatedInPrivateRoom)> GetParamsAsync<T>(T fileId, int version, string doc, bool editPossible, bool tryEdit, bool tryCoauth)
{
var lastVersion = true;
FileShare linkRight;
@ -105,7 +105,7 @@ public class DocumentServiceHelper
return await GetParamsAsync(file, lastVersion, linkRight, true, true, editPossible, tryEdit, tryCoauth);
}
public async Task<(File<T> File, Configuration<T> Configuration)> GetParamsAsync<T>(File<T> file, bool lastVersion, FileShare linkRight, bool rightToRename, bool rightToEdit, bool editPossible, bool tryEdit, bool tryCoauth)
public async Task<(File<T> File, Configuration<T> Configuration, bool LocatedInPrivateRoom)> GetParamsAsync<T>(File<T> file, bool lastVersion, FileShare linkRight, bool rightToRename, bool rightToEdit, bool editPossible, bool tryEdit, bool tryCoauth)
{
if (file == null)
{
@ -148,7 +148,7 @@ public class DocumentServiceHelper
&& (linkRight == FileShare.ReadWrite
|| await _fileSecurity.CanEditAsync(file));
rightToRename = rightToRename && rightToEdit && await _fileSecurity.CanEditAsync(file);
rightToRename = rightToRename && rightToEdit && await _fileSecurity.CanRenameAsync(file);
rightToReview = rightToReview
&& (linkRight == FileShare.Review || linkRight == FileShare.ReadWrite
@ -213,8 +213,17 @@ public class DocumentServiceHelper
rightToEdit = editPossible = false;
}
var locatedInPrivateRoom = false;
if (file.RootFolderType == FolderType.VirtualRooms)
{
var folderDao = _daoFactory.GetFolderDao<T>();
locatedInPrivateRoom = await DocSpaceHelper.LocatedInPrivateRoomAsync(file, folderDao);
}
if (file.Encrypted
&& file.RootFolderType != FolderType.Privacy)
&& file.RootFolderType != FolderType.Privacy && !locatedInPrivateRoom)
{
rightToEdit = editPossible = false;
rightToReview = reviewPossible = false;
@ -316,7 +325,7 @@ public class DocumentServiceHelper
configuration.Document.Title += $" ({file.CreateOnString})";
}
return (file, configuration);
return (file, configuration, locatedInPrivateRoom);
}
private async Task<bool> CanDownloadAsync<T>(FileSecurity fileSecurity, File<T> file, FileShare linkRight)

View File

@ -127,9 +127,7 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
Error = FilesCommonResource.ErrorMassage_FolderNotFound;
}
else if (folder.FolderType != FolderType.DEFAULT && folder.FolderType != FolderType.BUNCH
&& folder.FolderType != FolderType.FillingFormsRoom && folder.FolderType != FolderType.EditingRoom
&& folder.FolderType != FolderType.ReviewRoom && folder.FolderType != FolderType.ReadOnlyRoom
&& folder.FolderType != FolderType.CustomRoom)
&& !DocSpaceHelper.IsRoom(folder.FolderType))
{
Error = FilesCommonResource.ErrorMassage_SecurityException_DeleteFolder;
}
@ -169,7 +167,7 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
}
else
{
var immediately = _immediately || !FolderDao.UseTrashForRemove(folder);
var immediately = _immediately || FolderDao.UseTrashForRemoveAsync(folder);
if (immediately && FolderDao.UseRecursiveOperation(folder.Id, default(T)))
{
var files = await FileDao.GetFilesAsync(folder.Id).ToListAsync();
@ -187,19 +185,12 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
await FolderDao.DeleteFolderAsync(folder.Id);
if (isRoom)
if (isRoom && folder.ProviderEntry)
{
if (folder.ProviderEntry)
{
await ProviderDao.UpdateProviderInfoAsync(folder.ProviderId, null, FolderType.DEFAULT);
}
await ProviderDao.RemoveProviderInfoAsync(folder.ProviderId);
}
filesMessageService.Send(folder, _headers, MessageAction.RoomDeleted, folder.Title);
}
else
{
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
}
filesMessageService.Send(folder, _headers, isRoom ? MessageAction.RoomDeleted : MessageAction.FolderDeleted, folder.Title);
ProcessedFolder(folderId);
}
@ -216,19 +207,21 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
{
if (immediately)
{
if (isRoom)
{
await roomLogoManager.DeleteAsync(folder.Id);
}
await FolderDao.DeleteFolderAsync(folder.Id);
if (isRoom && folder.ProviderEntry)
{
await ProviderDao.RemoveProviderInfoAsync(folder.ProviderId);
}
if (isNeedSendActions)
{
if (isRoom)
{
await roomLogoManager.DeleteAsync(folder.Id);
filesMessageService.Send(folder, _headers, MessageAction.RoomDeleted, folder.Title);
}
else
{
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
}
filesMessageService.Send(folder, _headers, isRoom ? MessageAction.RoomDeleted : MessageAction.FolderDeleted, folder.Title);
}
}
else

View File

@ -42,7 +42,7 @@ class FileMoveCopyOperation : ComposeFileOperation<FileMoveCopyOperationData<str
internal class FileMoveCopyOperationData<T> : FileOperationData<T>
{
public string ThirdpartyFolderId { get; }
public string ThirdPartyFolderId { get; }
public int DaoFolderId { get; }
public bool Copy { get; }
public FileConflictResolveType ResolveType { get; }
@ -55,7 +55,7 @@ internal class FileMoveCopyOperationData<T> : FileOperationData<T>
{
if (!int.TryParse(toFolderId.GetString(), out var i))
{
ThirdpartyFolderId = toFolderId.GetString();
ThirdPartyFolderId = toFolderId.GetString();
}
else
{
@ -81,14 +81,15 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
private readonly FileConflictResolveType _resolveType;
private readonly IDictionary<string, StringValues> _headers;
private readonly ThumbnailSettings _thumbnailSettings;
private readonly Dictionary<T, Folder<T>> _parentRooms = new Dictionary<T, Folder<T>>();
public override FileOperationType OperationType => _copy ? FileOperationType.Copy : FileOperationType.Move;
public FileMoveCopyOperation(IServiceProvider serviceProvider, FileMoveCopyOperationData<T> data, ThumbnailSettings thumbnailSettings)
: base(serviceProvider, data)
: base(serviceProvider, data)
{
_daoFolderId = data.DaoFolderId;
_thirdpartyFolderId = data.ThirdpartyFolderId;
_thirdpartyFolderId = data.ThirdPartyFolderId;
_copy = data.Copy;
_resolveType = data.ResolveType;
@ -178,8 +179,8 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
var needToMark = new List<FileEntry<TTo>>();
var moveOrCopyFoldersTask = await MoveOrCopyFoldersAsync(scope, Folders, toFolder, _copy);
var moveOrCopyFilesTask = await MoveOrCopyFilesAsync(scope, Files, toFolder, _copy);
var moveOrCopyFoldersTask = await MoveOrCopyFoldersAsync(scope, Folders, toFolder, _copy, parentFolders);
var moveOrCopyFilesTask = await MoveOrCopyFilesAsync(scope, Files, toFolder, _copy, parentFolders);
needToMark.AddRange(moveOrCopyFoldersTask);
needToMark.AddRange(moveOrCopyFilesTask);
@ -191,7 +192,7 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
}
}
private async Task<List<FileEntry<TTo>>> MoveOrCopyFoldersAsync<TTo>(IServiceScope scope, List<T> folderIds, Folder<TTo> toFolder, bool copy)
private async Task<List<FileEntry<TTo>>> MoveOrCopyFoldersAsync<TTo>(IServiceScope scope, List<T> folderIds, Folder<TTo> toFolder, bool copy, IEnumerable<Folder<TTo>> toFolderParents)
{
var needToMark = new List<FileEntry<TTo>>();
@ -240,6 +241,10 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
{
Error = FilesCommonResource.ErrorMessage_UnarchiveRoom;
}
else if (!isRoom && folder.Private && !await CompliesPrivateRoomRulesAsync(folder, toFolderParents))
{
Error = FilesCommonResource.ErrorMassage_SecurityException_MoveFolder;
}
else if (!await FilesSecurity.CanDownloadAsync(folder))
{
Error = FilesCommonResource.ErrorMassage_SecurityException;
@ -289,8 +294,8 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
if (toFolder.ProviderId == folder.ProviderId // crossDao operation is always recursive
&& FolderDao.UseRecursiveOperation(folder.Id, toFolderId))
{
await MoveOrCopyFilesAsync(scope, await FileDao.GetFilesAsync(folder.Id).ToListAsync(), newFolder, copy);
await MoveOrCopyFoldersAsync(scope, await FolderDao.GetFoldersAsync(folder.Id).Select(f => f.Id).ToListAsync(), newFolder, copy);
await MoveOrCopyFilesAsync(scope, await FileDao.GetFilesAsync(folder.Id).ToListAsync(), newFolder, copy, toFolderParents);
await MoveOrCopyFoldersAsync(scope, await FolderDao.GetFoldersAsync(folder.Id).Select(f => f.Id).ToListAsync(), newFolder, copy, toFolderParents);
if (!copy)
{
@ -436,7 +441,7 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
return needToMark;
}
private async Task<List<FileEntry<TTo>>> MoveOrCopyFilesAsync<TTo>(IServiceScope scope, List<T> fileIds, Folder<TTo> toFolder, bool copy)
private async Task<List<FileEntry<TTo>>> MoveOrCopyFilesAsync<TTo>(IServiceScope scope, List<T> fileIds, Folder<TTo> toFolder, bool copy, IEnumerable<Folder<TTo>> toParentFolders)
{
var needToMark = new List<FileEntry<TTo>>();
@ -476,6 +481,10 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
{
Error = FilesCommonResource.ErrorMassage_SecurityException;
}
else if (!await CompliesPrivateRoomRulesAsync(file, toParentFolders))
{
Error = FilesCommonResource.ErrorMassage_SecurityException_MoveFile;
}
else if (file.RootFolderType == FolderType.Privacy
&& (copy || toFolder.RootFolderType != FolderType.Privacy))
{
@ -492,7 +501,7 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
try
{
var conflict = _resolveType == FileConflictResolveType.Duplicate
|| file.RootFolderType == FolderType.Privacy
|| file.RootFolderType == FolderType.Privacy || file.Encrypted
? null
: await fileDao.GetFileAsync(toFolderId, file.Title);
if (conflict == null)
@ -717,6 +726,36 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
}
return (false, error);
}
private async Task<bool> CompliesPrivateRoomRulesAsync<TTo>(FileEntry<T> entry, IEnumerable<Folder<TTo>> toFolderParents)
{
Folder<T> entryParentRoom;
if (_parentRooms.ContainsKey(entry.ParentId))
{
entryParentRoom = _parentRooms.Get(entry.ParentId);
}
else
{
entryParentRoom = await FolderDao.GetParentFoldersAsync(entry.ParentId).FirstOrDefaultAsync(f => f.Private && DocSpaceHelper.IsRoom(f.FolderType));
_parentRooms.Add(entry.ParentId, entryParentRoom);
}
var toFolderParentRoom = toFolderParents.FirstOrDefault(f => f.Private && DocSpaceHelper.IsRoom(f.FolderType));
if (entryParentRoom == null && toFolderParentRoom == null)
{
return true;
}
if (entryParentRoom != null && toFolderParentRoom == null
|| entryParentRoom == null && toFolderParentRoom != null)
{
return false;
}
return entryParentRoom.Id.Equals(toFolderParentRoom.Id) && !_copy;
}
}
[Scope]

View File

@ -108,6 +108,6 @@ public class AceShortWrapper
public class AceAdvancedSettingsWrapper
{
public bool DenyDownload { get; set; }
public bool DenySharing { get; set; }
}
public bool AllowSharingPrivateRoom { get; set; }
}

View File

@ -84,7 +84,12 @@ public class FileSharingAceHelper<T>
{
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException);
}
if (entry is Folder<T> { Private: true } && advancedSettings is not { AllowSharingPrivateRoom: true })
{
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException);
}
var ownerId = entry.RootFolderType == FolderType.USER ? entry.RootCreateBy : entry.CreateBy;
var entryType = entry.FileEntryType;
var recipients = new Dictionary<Guid, FileShare>();
@ -234,7 +239,7 @@ public class FileSharingAceHelper<T>
private async Task<List<AceWrapper>> FilterForRoomsAsync(FileEntry<T> entry, List<AceWrapper> aceWrappers, bool invite)
{
if (entry.FileEntryType == FileEntryType.File || entry.RootFolderType == FolderType.Archive || invite)
if (entry.FileEntryType == FileEntryType.File || entry.RootFolderType == FolderType.Archive || invite || entry is Folder<T> { Private : true })
{
return aceWrappers;
}
@ -325,9 +330,8 @@ public class FileSharingHelper
return
entry != null
&& ((entry.RootFolderType == FolderType.COMMON && _global.IsAdministrator)
|| (entry.RootFolderType == FolderType.VirtualRooms && _global.IsAdministrator)
|| (folder != null && (folder.FolderType == FolderType.FillingFormsRoom || folder.FolderType == FolderType.EditingRoom || folder.FolderType == FolderType.ReviewRoom ||
folder.FolderType == FolderType.ReadOnlyRoom || folder.FolderType == FolderType.CustomRoom) && await _fileSecurity.CanEditRoomAsync(entry))
|| (entry.RootFolderType == FolderType.VirtualRooms && (_global.IsAdministrator || await _fileSecurity.CanShare(entry)))
|| (folder != null && DocSpaceHelper.IsRoom(folder.FolderType) && await _fileSecurity.CanEditRoomAsync(entry))
|| !_userManager.GetUsers(_authContext.CurrentAccount.ID).IsVisitor(_userManager)
&& (entry.RootFolderType == FolderType.USER
&& (Equals(entry.RootId, _globalFolderHelper.FolderMy) || await _fileSecurity.CanShare(entry))

View File

@ -24,6 +24,9 @@
// 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.Files.Core.Helpers;
using ASC.Web.Files.ThirdPartyApp;
using FileShare = ASC.Files.Core.Security.FileShare;
namespace ASC.Files.Api;
@ -86,7 +89,7 @@ public class EditorControllerThirdparty : EditorController<string>
configuration.EditorConfig.Customization.GobackUrl = string.Empty;
configuration.EditorType = EditorType.External;
if (file.RootFolderType == FolderType.Privacy && PrivacyRoomSettings.GetEnabled(_settingsManager))
if (file.RootFolderType == FolderType.Privacy && PrivacyRoomSettings.GetEnabled(_settingsManager) || docParams.LocatedInPrivateRoom)
{
var keyPair = _encryptionKeyPairDtoHelper.GetKeyPair();
if (keyPair != null)
@ -220,7 +223,7 @@ public abstract class EditorController<T> : ApiControllerBase
var file = docParams.File;
configuration.EditorType = EditorType.External;
if (file.RootFolderType == FolderType.Privacy && PrivacyRoomSettings.GetEnabled(_settingsManager))
if (file.RootFolderType == FolderType.Privacy && PrivacyRoomSettings.GetEnabled(_settingsManager) || docParams.LocatedInPrivateRoom)
{
var keyPair = _encryptionKeyPairDtoHelper.GetKeyPair();
if (keyPair != null)

View File

@ -31,22 +31,22 @@ namespace ASC.Files.Api;
[ConstraintRoute("int")]
public class VirtualRoomsInternalController : VirtualRoomsController<int>
{
public VirtualRoomsInternalController(
FoldersControllerHelper<int> foldersControllerHelper,
GlobalFolderHelper globalFolderHelper,
FileOperationDtoHelper fileOperationDtoHelper,
SecurityControllerHelper<int> securityControllerHelper,
CoreBaseSettings coreBaseSettings,
AuthContext authContext,
RoomInvitationLinksService roomLinksService,
CustomTagsService<int> customTagsService,
RoomLogoManager roomLogoManager,
StudioNotifyService studioNotifyService,
FileStorageService<int> fileStorageService,
FileSecurity fileSecurity,
FileSecurityCommon fileSecurityCommon,
EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
public VirtualRoomsInternalController(
FoldersControllerHelper<int> foldersControllerHelper,
GlobalFolderHelper globalFolderHelper,
FileOperationDtoHelper fileOperationDtoHelper,
SecurityControllerHelper<int> securityControllerHelper,
CoreBaseSettings coreBaseSettings,
AuthContext authContext,
RoomInvitationLinksService roomLinksService,
CustomTagsService<int> customTagsService,
RoomLogoManager roomLogoManager,
StudioNotifyService studioNotifyService,
FileStorageService<int> fileStorageService,
FileSecurity fileSecurity,
FileSecurityCommon fileSecurityCommon,
EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
FileDtoHelper fileDtoHelper) : base(foldersControllerHelper, globalFolderHelper, fileOperationDtoHelper, securityControllerHelper, coreBaseSettings, authContext, roomLinksService, customTagsService, roomLogoManager, studioNotifyService, fileStorageService, fileSecurity, fileSecurityCommon, emailValidationKeyProvider, folderDtoHelper, fileDtoHelper)
{
}
@ -71,16 +71,30 @@ public class VirtualRoomsInternalController : VirtualRoomsController<int>
{
ErrorIfNotDocSpace();
var room = await _fileStorageService.CreateRoomAsync(inDto.Title, inDto.RoomType);
var room = await _fileStorageService.CreateRoomAsync(inDto.Title, inDto.RoomType, inDto.Private, inDto.Share, inDto.Notify, inDto.SharingMessage);
return await _folderDtoHelper.GetAsync(room);
}
}
public class VirtualRoomsThirdpartyController : VirtualRoomsController<string>
public class VirtualRoomsThirdPartyController : VirtualRoomsController<string>
{
public VirtualRoomsThirdpartyController(FoldersControllerHelper<string> foldersControllerHelper, GlobalFolderHelper globalFolderHelper, FileOperationDtoHelper fileOperationDtoHelper, SecurityControllerHelper<string> securityControllerHelper, CoreBaseSettings coreBaseSettings, AuthContext authContext, RoomInvitationLinksService roomLinksService, CustomTagsService<string> customTagsService, RoomLogoManager roomLogoManager, StudioNotifyService studioNotifyService, FileStorageService<string> fileStorageService, FileSecurity fileSecurity, FileSecurityCommon fileSecurityCommon, EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
public VirtualRoomsThirdPartyController(
FoldersControllerHelper<string> foldersControllerHelper,
GlobalFolderHelper globalFolderHelper,
FileOperationDtoHelper fileOperationDtoHelper,
SecurityControllerHelper<string> securityControllerHelper,
CoreBaseSettings coreBaseSettings,
AuthContext authContext,
RoomInvitationLinksService roomLinksService,
CustomTagsService<string> customTagsService,
RoomLogoManager roomLogoManager,
StudioNotifyService studioNotifyService,
FileStorageService<string> fileStorageService,
FileSecurity fileSecurity,
FileSecurityCommon fileSecurityCommon,
EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
FileDtoHelper fileDtoHelper) : base(foldersControllerHelper, globalFolderHelper, fileOperationDtoHelper, securityControllerHelper, coreBaseSettings, authContext, roomLinksService, customTagsService, roomLogoManager, studioNotifyService, fileStorageService, fileSecurity, fileSecurityCommon, emailValidationKeyProvider, folderDtoHelper, fileDtoHelper)
{
}
@ -108,7 +122,7 @@ public class VirtualRoomsThirdpartyController : VirtualRoomsController<string>
{
ErrorIfNotDocSpace();
var room = await _fileStorageService.CreateThirdpartyRoomAsync(inDto.Title, inDto.RoomType, id);
var room = await _fileStorageService.CreateThirdPartyRoomAsync(inDto.Title, inDto.RoomType, id, inDto.Private, inDto.Share, inDto.Notify, inDto.SharingMessage);
return await _folderDtoHelper.GetAsync(room);
}
@ -131,8 +145,8 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
private readonly FileSecurityCommon _fileSecurityCommon;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
protected VirtualRoomsController(FoldersControllerHelper<T> foldersControllerHelper, GlobalFolderHelper globalFolderHelper, FileOperationDtoHelper fileOperationDtoHelper, SecurityControllerHelper<T> securityControllerHelper, CoreBaseSettings coreBaseSettings, AuthContext authContext, RoomInvitationLinksService roomLinksService, CustomTagsService<T> customTagsService, RoomLogoManager roomLogoManager, StudioNotifyService studioNotifyService, FileStorageService<T> fileStorageService, FileSecurity fileSecurity, FileSecurityCommon fileSecurityCommon, EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
protected VirtualRoomsController(FoldersControllerHelper<T> foldersControllerHelper, GlobalFolderHelper globalFolderHelper, FileOperationDtoHelper fileOperationDtoHelper, SecurityControllerHelper<T> securityControllerHelper, CoreBaseSettings coreBaseSettings, AuthContext authContext, RoomInvitationLinksService roomLinksService, CustomTagsService<T> customTagsService, RoomLogoManager roomLogoManager, StudioNotifyService studioNotifyService, FileStorageService<T> fileStorageService, FileSecurity fileSecurity, FileSecurityCommon fileSecurityCommon, EmailValidationKeyProvider emailValidationKeyProvider,
FolderDtoHelper folderDtoHelper,
FileDtoHelper fileDtoHelper) : base(folderDtoHelper, fileDtoHelper)
{
_foldersControllerHelper = foldersControllerHelper;
@ -323,20 +337,20 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
public async IAsyncEnumerable<FileShareDto> SetRoomSecurityAsync(T id, SecurityInfoRequestDto inDto)
{
ErrorIfNotDocSpace();
IAsyncEnumerable<FileShareDto> result;
if (!string.IsNullOrEmpty(inDto.Key))
{
result = SetRoomSecurityByLinkAsync(id, _authContext.CurrentAccount.ID, inDto.Access, inDto.Key);
}
else
{
result = _securityControllerHelper.SetFolderSecurityInfoAsync(id, inDto.Share, inDto.Notify, inDto.SharingMessage);
}
await foreach (var r in result)
{
yield return r;
}
else
{
result = _securityControllerHelper.SetFolderSecurityInfoAsync(id, inDto.Share, inDto.Notify, inDto.SharingMessage);
}
await foreach (var r in result)
{
yield return r;
}
}
@ -592,9 +606,9 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
Access = access
};
await foreach (var s in _securityControllerHelper.SetFolderSecurityInfoAsync(id, new[] { share }, false, null, true))
{
yield return s;
await foreach (var s in _securityControllerHelper.SetFolderSecurityInfoAsync(id, new[] { share }, false, null, true))
{
yield return s;
}
}
@ -602,7 +616,7 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
{
var room = await _fileStorageService.GetFolderAsync(id);
if ((share == FileShare.RoomManager && !_fileSecurityCommon.IsAdministrator(_authContext.CurrentAccount.ID))
if ((share == FileShare.RoomManager && !_fileSecurityCommon.IsAdministrator(_authContext.CurrentAccount.ID))
|| !await _fileSecurity.CanEditRoomAsync(room))
{
throw new InvalidOperationException("You don't have the rights to invite users to the room");
@ -622,8 +636,8 @@ public class VirtualRoomsCommonController : ApiControllerBase
private readonly SetupInfo _setupInfo;
private readonly FileSizeComment _fileSizeComment;
public VirtualRoomsCommonController(FileStorageService<int> fileStorageService, FolderContentDtoHelper folderContentDtoHelper, GlobalFolderHelper globalFolderHelper, CoreBaseSettings coreBaseSettings, ApiContext apiContext, CustomTagsService<int> customTagsService, RoomLogoManager roomLogoManager, SetupInfo setupInfo, FileSizeComment fileSizeComment,
FolderDtoHelper folderDtoHelper,
public VirtualRoomsCommonController(FileStorageService<int> fileStorageService, FolderContentDtoHelper folderContentDtoHelper, GlobalFolderHelper globalFolderHelper, CoreBaseSettings coreBaseSettings, ApiContext apiContext, CustomTagsService<int> customTagsService, RoomLogoManager roomLogoManager, SetupInfo setupInfo, FileSizeComment fileSizeComment,
FolderDtoHelper folderDtoHelper,
FileDtoHelper fileDtoHelper) : base(folderDtoHelper, fileDtoHelper)
{
_fileStorageService = fileStorageService;
@ -693,7 +707,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
RoomFilterType.ReadOnlyRoomOnly => FilterType.ReadOnlyRooms,
RoomFilterType.EditingRoomOnly => FilterType.EditingRooms,
RoomFilterType.ReviewRoomOnly => FilterType.ReviewRooms,
RoomFilterType.CustomRoomOnly => FilterType.CustomRooms,
RoomFilterType.CustomRoomOnly => FilterType.CustomRooms,
RoomFilterType.FoldersOnly => FilterType.FoldersOnly,
_ => FilterType.None
};
@ -710,7 +724,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
var count = Convert.ToInt32(_apiContext.Count);
var filterValue = _apiContext.FilterValue;
var content = await _fileStorageService.GetFolderItemsAsync(parentId, startIndex, count, filter, false, subjectId, filterValue,
var content = await _fileStorageService.GetFolderItemsAsync(parentId, startIndex, count, filter, false, subjectId, filterValue,
searchInContent ?? false, withSubfolders ?? false, orderBy, searchArea ?? SearchArea.Active, withoutTags ?? false, tagNames, withoutMe ?? false);
var dto = await _folderContentDtoHelper.GetAsync(content, startIndex);
@ -806,7 +820,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
try
{
if (formCollection.Files.Count != 0)
if (formCollection.Files.Count != 0)
{
var roomLogo = formCollection.Files[0];