diff --git a/products/ASC.Files/Core/ApiModels/ResponseDto/ConfigurationDto.cs b/products/ASC.Files/Core/ApiModels/ResponseDto/ConfigurationDto.cs index 489ea5bff2..03242d661a 100644 --- a/products/ASC.Files/Core/ApiModels/ResponseDto/ConfigurationDto.cs +++ b/products/ASC.Files/Core/ApiModels/ResponseDto/ConfigurationDto.cs @@ -255,7 +255,7 @@ public async Task> Convert(Configuration configurat 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), diff --git a/products/ASC.Files/Core/Core/Security/ExternalShare.cs b/products/ASC.Files/Core/Core/Security/ExternalShare.cs index 6b9d6c326c..986443c052 100644 --- a/products/ASC.Files/Core/Core/Security/ExternalShare.cs +++ b/products/ASC.Files/Core/Core/Security/ExternalShare.cs @@ -33,8 +33,7 @@ public class ExternalShare(Global global, IHttpContextAccessor httpContextAccessor, BaseCommonLinkUtility commonLinkUtility, FilesLinkUtility filesLinkUtility, - FileUtility fileUtility, - ILogger logger) + FileUtility fileUtility) { private ExternalSessionSnapshot _snapshot; private string _dbKey; @@ -122,9 +121,17 @@ public async Task ValidateRecordAsync(FileShareRecord record, stri if (string.IsNullOrEmpty(passwordKey)) { passwordKey = cookiesManager.GetCookies(CookiesType.ShareLink, record.Subject.ToString(), true); - logger.LogDebug("Validate record. cookies password key {passwordKey}", passwordKey); + if (string.IsNullOrEmpty(passwordKey)) + { + var key = GetKey(); + if (!string.IsNullOrEmpty(key)) + { + var data = await ParseShareKeyAsync(key); + passwordKey = data.Password; + } + } } - logger.LogDebug("Validate record. password key {passwordKey} record password {recordPassword}", passwordKey, record.Options.Password); + if (passwordKey == record.Options.Password) { return Status.Ok; @@ -169,11 +176,22 @@ public string GetKey() return string.IsNullOrEmpty(key) ? null : key; } - public async Task ParseShareKeyAsync(string key) + public async Task ParseShareKeyAsync(string key) { ArgumentException.ThrowIfNullOrEmpty(key); - - return Signature.Read(key, await GetDbKeyAsync()); + + var stringKey = Signature.Read(key, await GetDbKeyAsync()); + + if (!stringKey.StartsWith('{') || !stringKey.EndsWith('}')) + { + return new TokenData + { + Id = Guid.TryParse(stringKey, out var id) ? id : Guid.Empty + }; + } + + var token = JsonSerializer.Deserialize(stringKey); + return token; } public async Task GetLinkIdAsync() @@ -189,8 +207,8 @@ public async Task 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() @@ -277,9 +295,20 @@ public void Initialize(ExternalSessionSnapshot snapshot) _snapshot = snapshot; } - public async Task CreateShareKeyAsync(Guid linkId) + public async Task 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 GetDbKeyAsync() @@ -374,4 +403,10 @@ public enum Status RequiredPassword, InvalidPassword, ExternalAccessDenied +} + +public record TokenData +{ + public Guid Id { get; set; } + public string Password { get; set; } } \ No newline at end of file diff --git a/products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs b/products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs index ff75339ea7..92c0e0ba82 100644 --- a/products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs +++ b/products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs @@ -39,13 +39,12 @@ public async Task 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(); - var record = await securityDao.GetSharesAsync(new[] { linkId }).FirstOrDefaultAsync(); + var record = await securityDao.GetSharesAsync([data.Id]).FirstOrDefaultAsync(); if (record == null) { - logger.LogDebug(" 1. Result Validate External Link: {result}. File id: {fileId}. Record: {record}", JsonSerializer.Serialize(result), fileId, JsonSerializer.Serialize(record)); return result; } @@ -54,7 +53,6 @@ public async Task ValidateAsync(string key, string password = nu if (status != Status.Ok && status != Status.RequiredPassword) { - logger.LogDebug(" 2. Result Validate External Link: {result}. File id: {fileId}. Record: {record}", JsonSerializer.Serialize(result), fileId, JsonSerializer.Serialize(record)); return result; } @@ -91,7 +89,7 @@ public async Task ValidateAsync(string key, string password = nu result.Access = record.Share; result.TenantId = record.TenantId; - result.LinkId = linkId; + result.LinkId = data.Id; if (securityContext.IsAuthenticated) { diff --git a/products/ASC.Files/Core/Services/DocumentService/Configuration.cs b/products/ASC.Files/Core/Services/DocumentService/Configuration.cs index 04505a85b1..77032c168f 100644 --- a/products/ASC.Files/Core/Services/DocumentService/Configuration.cs +++ b/products/ASC.Files/Core/Services/DocumentService/Configuration.cs @@ -244,18 +244,26 @@ public async Task GetUserAsync() return _user; } - public async Task GetCallbackUrl(string fileId, string fillingSessionId) + public async Task GetCallbackUrl(File file, string fillingSessionId) { if (!ModeWrite) { return null; } - var callbackUrl = await documentServiceTrackerHelper.GetCallbackUrlAsync(fileId); + var callbackUrl = await documentServiceTrackerHelper.GetCallbackUrlAsync(file.Id.ToString()); - callbackUrl = !string.IsNullOrEmpty(fillingSessionId) ? QueryHelpers.AddQueryString(callbackUrl, FilesLinkUtility.FillingSessionId, fillingSessionId) : callbackUrl; + callbackUrl = !string.IsNullOrEmpty(fillingSessionId) + ? QueryHelpers.AddQueryString(callbackUrl, FilesLinkUtility.FillingSessionId, fillingSessionId) + : callbackUrl; - return externalShare.GetUrlWithShare(callbackUrl); + if (file.ShareRecord is not { IsLink: true } || string.IsNullOrEmpty(file.ShareRecord.Options?.Password)) + { + return externalShare.GetUrlWithShare(callbackUrl); + } + + var key = await externalShare.CreateShareKeyAsync(file.ShareRecord.Subject, file.ShareRecord.Options?.Password); + return externalShare.GetUrlWithShare(callbackUrl, key); } public async Task GetCoEditingAsync()