Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/hotfix/v2.6.3' into develop
Browse files Browse the repository at this point in the history
# Conflicts:
#	products/ASC.Files/Core/Core/Security/FileSecurity.cs
#	products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs
#	products/ASC.Files/Core/Utils/EntryManager.cs
  • Loading branch information
pavelbannov committed Oct 7, 2024
2 parents e085690 + 6ab30c7 commit 6c68bd4
Show file tree
Hide file tree
Showing 46 changed files with 252 additions and 215 deletions.
2 changes: 1 addition & 1 deletion common/ASC.Common/Utils/HttpRequestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,6 @@ public static bool DesktopApp(this HttpRequest request)

public static bool MobileApp(this HttpRequest request)
{
return !string.IsNullOrEmpty(request.Headers[HeaderNames.UserAgent]) && (request.Headers[HeaderNames.UserAgent].Contains("iOS") || request.Headers[HeaderNames.UserAgent].Contains("Android"));
return !string.IsNullOrEmpty(request.Headers[HeaderNames.UserAgent]) && (request.Headers[HeaderNames.UserAgent].ToString().Contains("iPhone") || request.Headers[HeaderNames.UserAgent].ToString().Contains("iOS") || request.Headers[HeaderNames.UserAgent].ToString().Contains("Android"));
}
}
14 changes: 12 additions & 2 deletions products/ASC.Files/Core/ApiModels/ResponseDto/ConfigurationDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ public class ConfigurationConverter<T>(
FileDtoHelper fileDtoHelper,
EditorConfigurationConverter<T> editorConfigurationConverter,
DocumentConfigConverter<T> documentConfigConverter,
DocumentServiceHelper documentServiceHelper)
DocumentServiceHelper documentServiceHelper,
ExternalShare externalShare)
{
public async Task<ConfigurationDto<T>> Convert(Configuration<T> source, File<T> file, string fillingSessionId = "")
{
Expand All @@ -231,6 +232,15 @@ public async Task<ConfigurationDto<T>> Convert(Configuration<T> source, File<T>
result.Token = documentServiceHelper.GetSignature(result);
result.File = await fileDtoHelper.GetAsync(file);
result.Type = source.Type;

if (source.EditorType == EditorType.Embedded)
{
var shareParam = file.ShareRecord != null
? $"&{FilesLinkUtility.ShareKey}={await externalShare.CreateShareKeyAsync(file.ShareRecord.Subject)}"
: "";

result.EditorConfig.Embedded.ShareLinkParam = $"&{FilesLinkUtility.FileId}={file.Id}{shareParam}";
}
return result;
}
}
Expand All @@ -251,7 +261,7 @@ public async Task<EditorConfigurationDto> Convert(Configuration<T> configuration
var fileType = configuration.GetFileType(file);
var result = new EditorConfigurationDto
{
CallbackUrl = await source.GetCallbackUrl(file.Id.ToString(), fillingSessionId),
CallbackUrl = await source.GetCallbackUrl(file, fillingSessionId),
CoEditing = await source.GetCoEditingAsync(),
CreateUrl = await source.GetCreateUrl(configuration.EditorType, fileType),
Customization = await configConverter.Convert(configuration, file),
Expand Down
1 change: 1 addition & 0 deletions products/ASC.Files/Core/Core/Dao/TeamlabDao/FileDao.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ await strategy.ExecuteAsync(async () =>
{
properties.FormFilling.StartFilling = true;
properties.FormFilling.CollectFillForm = true;
properties.FormFilling.OriginalFormId = file.Id;
await fileDao.SaveProperties(file.Id, properties);
var count = await fileStorageService.GetPureSharesCountAsync(currentRoom.Id, FileEntryType.Folder, ShareFilterType.UserOrGroup, "");
if (file.IsForm)
Expand Down
7 changes: 2 additions & 5 deletions products/ASC.Files/Core/Core/FileStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,7 @@ await folderDao.GetFirstParentTypeFromFileEntryAsync(parent) :
}
if (parent.FolderType is FolderType.FormFillingFolderDone or FolderType.FormFillingFolderInProgress)
{
var (currentRoomId, _) = await folderDao.GetParentRoomInfoFromFileEntryAsync(parent);
var room = await folderDao.GetFolderAsync((T)Convert.ChangeType(currentRoomId, typeof(T))).NotFoundIfNull();
var ace = await fileSharing.GetPureSharesAsync(room, new List<Guid> { authContext.CurrentAccount.ID }).FirstOrDefaultAsync();

if (ace is { Access: FileShare.FillForms })
if (parent.ShareRecord is { Share: FileShare.FillForms })
{
subjectId = authContext.CurrentAccount.ID;
}
Expand Down Expand Up @@ -1362,6 +1358,7 @@ public async Task StartFillingAsync<T>(T fileId)
var properties = await fileDao.GetProperties(fileId) ?? new EntryProperties<T> { FormFilling = new FormFillingProperties<T>() };
properties.FormFilling.StartFilling = true;
properties.FormFilling.CollectFillForm = true;
properties.FormFilling.OriginalFormId = fileId;

await fileDao.SaveProperties(fileId, properties);

Expand Down
4 changes: 3 additions & 1 deletion products/ASC.Files/Core/Core/History/AuditInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ public class AuditInterpreter(IServiceProvider serviceProvider)
{ (int)MessageAction.RoomExternalLinkCreated, new RoomExternalLinkCreatedInterpreter() },
{ (int)MessageAction.RoomExternalLinkRenamed, new RoomExternalLinkRenamedInterpreter() },
{ (int)MessageAction.RoomExternalLinkDeleted, new RoomExternalLinkDeletedInterpreter() },
{ (int)MessageAction.RoomExternalLinkRevoked, new RoomExternalLinkRevokedInterpreter() }
{ (int)MessageAction.RoomExternalLinkRevoked, new RoomExternalLinkRevokedInterpreter() },
{ (int)MessageAction.FormSubmit, new UserFileUpdatedInterpreter() },
{ (int)MessageAction.FormOpenedForFilling, new UserFileUpdatedInterpreter() }
}.ToFrozenDictionary();

public ValueTask<HistoryEntry> ToHistoryAsync(DbAuditEvent @event)
Expand Down
4 changes: 3 additions & 1 deletion products/ASC.Files/Core/Core/History/HistoryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ public class HistoryService(
MessageAction.RoomExternalLinkCreated,
MessageAction.RoomExternalLinkRenamed,
MessageAction.RoomExternalLinkDeleted,
MessageAction.RoomExternalLinkRevoked
MessageAction.RoomExternalLinkRevoked,
MessageAction.FormSubmit,
MessageAction.FormOpenedForFilling
];

public async IAsyncEnumerable<HistoryEntry> GetHistoryAsync(int entryId, FileEntryType entryType, int offset, int count)
Expand Down
67 changes: 59 additions & 8 deletions products/ASC.Files/Core/Core/Security/ExternalShare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ public async Task<Status> ValidateRecordAsync<T>(FileShareRecord<T> record, stri
if (string.IsNullOrEmpty(passwordKey))
{
passwordKey = cookiesManager.GetCookies(CookiesType.ShareLink, record.Subject.ToString(), true);
if (string.IsNullOrEmpty(passwordKey))
{
var key = GetKey();
if (!string.IsNullOrEmpty(key))
{
var data = await ParseShareKeyAsync(key);
passwordKey = data.Password;
}
}
}

if (passwordKey == record.Options.Password)
Expand Down Expand Up @@ -167,11 +176,36 @@ public string GetKey()
return string.IsNullOrEmpty(key) ? null : key;
}

public async Task<Guid> ParseShareKeyAsync(string key)
public async Task<TokenData> ParseShareKeyAsync(string key)
{
ArgumentException.ThrowIfNullOrEmpty(key);

return Signature.Read<Guid>(key, await GetDbKeyAsync());
if (string.IsNullOrEmpty(key))
{
return new TokenData
{
Id = Guid.Empty
};
}

var stringKey = Signature.Read<string>(key, await GetDbKeyAsync());

if (string.IsNullOrEmpty(stringKey))
{
return new TokenData
{
Id = Guid.Empty
};
}

if (!stringKey.StartsWith('{') || !stringKey.EndsWith('}'))
{
return new TokenData
{
Id = Guid.TryParse(stringKey, out var id) ? id : Guid.Empty
};
}

var token = JsonSerializer.Deserialize<TokenData>(stringKey);
return token;
}

public async Task<Guid> GetLinkIdAsync()
Expand All @@ -187,8 +221,8 @@ public async Task<Guid> GetLinkIdAsync()
return Guid.Empty;
}

var linkId = await ParseShareKeyAsync(key);
return linkId == Guid.Empty ? Guid.Empty : linkId;
var data = await ParseShareKeyAsync(key);
return data?.Id ?? Guid.Empty;
}

public Guid GetSessionId()
Expand Down Expand Up @@ -275,9 +309,20 @@ public void Initialize(ExternalSessionSnapshot snapshot)
_snapshot = snapshot;
}

public async Task<string> CreateShareKeyAsync(Guid linkId)
public async Task<string> CreateShareKeyAsync(Guid linkId, string password = null)
{
return Signature.Create(linkId, await GetDbKeyAsync());
if (string.IsNullOrEmpty(password))
{
return Signature.Create(linkId, await GetDbKeyAsync());
}

var data = new TokenData
{
Id = linkId,
Password = password
};

return Signature.Create(JsonSerializer.Serialize(data), await GetDbKeyAsync());
}

private async Task<string> GetDbKeyAsync()
Expand Down Expand Up @@ -372,4 +417,10 @@ public enum Status
RequiredPassword,
InvalidPassword,
ExternalAccessDenied
}

public record TokenData
{
public Guid Id { get; set; }
public string Password { get; set; }
}
20 changes: 18 additions & 2 deletions products/ASC.Files/Core/Core/Security/FileSecurity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,8 @@ private async Task<bool> FilterEntryAsync<T>(FileEntry<T> e, FilesSecurityAction
var isRoom = folder != null && DocSpaceHelper.IsRoom(folder.FolderType);

if (file != null &&
action is FilesSecurityActions.EditForm or FilesSecurityActions.FillForms &&
(action == FilesSecurityActions.EditForm ||
action == FilesSecurityActions.FillForms) &&
!file.IsForm)
{
return false;
Expand Down Expand Up @@ -1139,6 +1140,22 @@ FilesSecurityActions.SubmitToFormGallery or
e.Access = ace?.Share ?? defaultShare;
e.Access = e.RootFolderType is FolderType.ThirdpartyBackup ? FileShare.Restrict : e.Access;

if (file != null)
{
var fileType = FileUtility.GetFileTypeByFileName(file.Title);
if (fileType is FileType.Pdf or FileType.Spreadsheet)
{
var parentFolders = await GetFileParentFolders(file.ParentId);
if (parentFolders.Exists(parent => parent.FolderType is FolderType.ReadyFormFolder or FolderType.InProcessFormFolder))
{
if (ace is { Share: FileShare.FillForms } && userId != file.CreateBy)
{
return false;
}
}
}
}

if (ace is { SubjectType: SubjectType.ExternalLink or SubjectType.PrimaryExternalLink } && ace.Subject != userId &&
await externalShare.ValidateRecordAsync(ace, null, isAuthenticated, e) != Status.Ok)
{
Expand Down Expand Up @@ -1525,7 +1542,6 @@ await externalShare.ValidateRecordAsync(ace, null, isAuthenticated, e) != Status
{
e.Access = FileShare.None; //HACK: for client
}

return false;

bool MustConvert(FileEntry entry)
Expand Down
6 changes: 3 additions & 3 deletions products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ public async Task<ValidationInfo> ValidateAsync(string key, string password = nu
Access = FileShare.Restrict
};

var linkId = await externalShare.ParseShareKeyAsync(key);
var data = await externalShare.ParseShareKeyAsync(key);
var securityDao = daoFactory.GetSecurityDao<string>();

var record = await securityDao.GetSharesAsync([linkId]).FirstOrDefaultAsync();
var record = await securityDao.GetSharesAsync([data.Id]).FirstOrDefaultAsync();
if (record == null)
{
return result;
Expand Down Expand Up @@ -87,7 +87,7 @@ public async Task<ValidationInfo> ValidateAsync(string key, string password = nu

result.Access = record.Share;
result.TenantId = record.TenantId;
result.LinkId = linkId;
result.LinkId = data.Id;

if (securityContext.IsAuthenticated)
{
Expand Down
101 changes: 74 additions & 27 deletions products/ASC.Files/Core/Helpers/ThirdpartyConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,47 +65,94 @@ public bool SupportInclusion(IDaoFactory daoFactory)
return SupportBoxInclusion || SupportDropboxInclusion || SupportDocuSignInclusion || SupportGoogleDriveInclusion || SupportOneDriveInclusion || SupportSharePointInclusion || SupportWebDavInclusion || SupportNextcloudInclusion || SupportOwncloudInclusion || SupportkDriveInclusion || SupportYandexInclusion;
}

public bool SupportBoxInclusion => ThirdPartyProviders.Contains("box") && BoxLoginProvider.IsEnabled;
public bool SupportBoxInclusion => ThirdPartyProviders.Contains(BoxKey) && BoxLoginProvider.IsEnabled;

public bool SupportDropboxInclusion => ThirdPartyProviders.Contains("dropboxv2") && DropboxLoginProvider.IsEnabled;
public bool SupportDropboxInclusion => ThirdPartyProviders.Contains(DropboxKey) && DropboxLoginProvider.IsEnabled;

public bool SupportOneDriveInclusion => ThirdPartyProviders.Contains("onedrive") && OneDriveLoginProvider.IsEnabled;
public bool SupportOneDriveInclusion => ThirdPartyProviders.Contains(OneDriveKey) && OneDriveLoginProvider.IsEnabled;

public bool SupportSharePointInclusion => ThirdPartyProviders.Contains("sharepoint");
public bool SupportSharePointInclusion => ThirdPartyProviders.Contains(SharePointKey);

public bool SupportWebDavInclusion => ThirdPartyProviders.Contains("webdav");
public bool SupportWebDavInclusion => ThirdPartyProviders.Contains(WebDavKey);

public bool SupportNextcloudInclusion => ThirdPartyProviders.Contains("nextcloud");
public bool SupportNextcloudInclusion => ThirdPartyProviders.Contains(NextcloudKey);

public bool SupportOwncloudInclusion => ThirdPartyProviders.Contains("owncloud");
public bool SupportOwncloudInclusion => ThirdPartyProviders.Contains(OwncloudKey);

public bool SupportkDriveInclusion => ThirdPartyProviders.Contains("kdrive");
public bool SupportkDriveInclusion => ThirdPartyProviders.Contains(KDriveKey);

public bool SupportYandexInclusion => ThirdPartyProviders.Contains("yandex");
public bool SupportYandexInclusion => ThirdPartyProviders.Contains(YandexKey);

public bool SupportDocuSignInclusion => ThirdPartyProviders.Contains("docusign") && DocuSignLoginProvider.IsEnabled;

public bool SupportGoogleDriveInclusion => ThirdPartyProviders.Contains("google") && GoogleLoginProvider.IsEnabled;
public bool SupportDocuSignInclusion => ThirdPartyProviders.Contains(DocuSignKey) && DocuSignLoginProvider.IsEnabled;

public bool SupportGoogleDriveInclusion => ThirdPartyProviders.Contains(GoogleDriveKey) && GoogleLoginProvider.IsEnabled;

private static string BoxKey => "box";
private static string DropboxKey => "dropboxv2";
private static string GoogleDriveKey => "google";
private static string OneDriveKey => "onedrive";
private static string SharePointKey => "sharepoint";
private static string WebDavKey => "webdav";
private static string NextcloudKey => "nextcloud";
private static string OwncloudKey => "owncloud";
private static string KDriveKey => "kdrive";
private static string YandexKey => "yandex";
private static string DocuSignKey => "docusign";

public List<ProviderDto> GetAllProviders()
{
var webDavKey = ProviderTypes.WebDav.ToStringFast();

var providers = new List<ProviderDto>
{
new("Box", ProviderTypes.Box.ToStringFast(), BoxLoginProvider.IsEnabled, true, BoxLoginProvider.RedirectUri,
ClientId: BoxLoginProvider.ClientID),
new("Dropbox", ProviderTypes.DropboxV2.ToStringFast(), DropboxLoginProvider.IsEnabled, true, DropboxLoginProvider.RedirectUri,
ClientId: DropboxLoginProvider.ClientID),
new("GoogleDrive", ProviderTypes.GoogleDrive.ToStringFast(), GoogleLoginProvider.IsEnabled, true, GoogleLoginProvider.RedirectUri,
ClientId: GoogleLoginProvider.ClientID),
new("OneDrive", ProviderTypes.OneDrive.ToStringFast(), OneDriveLoginProvider.IsEnabled, true, OneDriveLoginProvider.RedirectUri,
ClientId: OneDriveLoginProvider.ClientID),
new("kDrive", webDavKey, true),
new("WebDav", webDavKey, true, RequiredConnectionUrl: true),
new("Nextcloud", webDavKey, true, RequiredConnectionUrl: true),
new("ownCloud", webDavKey, true, RequiredConnectionUrl: true)
};
var providers = new List<ProviderDto>(ThirdPartyProviders.Count);

if (ThirdPartyProviders.Contains(BoxKey))
{
providers.Add(new ProviderDto("Box", ProviderTypes.Box.ToStringFast(), BoxLoginProvider.IsEnabled, true, BoxLoginProvider.RedirectUri,
ClientId: BoxLoginProvider.ClientID));
}

if (ThirdPartyProviders.Contains(DropboxKey))
{
providers.Add(new ProviderDto("Dropbox", ProviderTypes.DropboxV2.ToStringFast(), DropboxLoginProvider.IsEnabled, true, DropboxLoginProvider.RedirectUri,
ClientId: DropboxLoginProvider.ClientID));
}

if (ThirdPartyProviders.Contains(GoogleDriveKey))
{
providers.Add(new ProviderDto("GoogleDrive", ProviderTypes.GoogleDrive.ToStringFast(), GoogleLoginProvider.IsEnabled, true, GoogleLoginProvider.RedirectUri,
ClientId: GoogleLoginProvider.ClientID));
}

if (ThirdPartyProviders.Contains(OneDriveKey))
{
providers.Add(new ProviderDto("OneDrive", ProviderTypes.OneDrive.ToStringFast(), OneDriveLoginProvider.IsEnabled, true, OneDriveLoginProvider.RedirectUri,
ClientId: OneDriveLoginProvider.ClientID));
}

if (ThirdPartyProviders.Contains(KDriveKey))
{
providers.Add(new ProviderDto("kDrive", webDavKey, true));
}

if (ThirdPartyProviders.Contains(YandexKey))
{
providers.Add(new ProviderDto("Yandex", webDavKey, true));
}

if (ThirdPartyProviders.Contains(WebDavKey))
{
providers.Add(new ProviderDto("WebDav", webDavKey, true, RequiredConnectionUrl: true));
}

if (ThirdPartyProviders.Contains(NextcloudKey))
{
providers.Add(new ProviderDto("Nextcloud", webDavKey, true, RequiredConnectionUrl: true));
}

if (ThirdPartyProviders.Contains(OwncloudKey))
{
providers.Add(new ProviderDto("ownCloud", webDavKey, true, RequiredConnectionUrl: true));
}

return providers;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6c68bd4

Please sign in to comment.