Skip to content

Commit

Permalink
Merge pull request #128 from ONLYOFFICE/bugfix/copy-file-link
Browse files Browse the repository at this point in the history
Bugfix/copy file link
  • Loading branch information
AlexeySafronov authored Dec 27, 2023
2 parents f083412 + fbd127e commit be6a206
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 54 deletions.
11 changes: 7 additions & 4 deletions products/ASC.Files/Core/ApiModels/ResponseDto/FileDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public class FileDtoHelper : FileEntryDtoHelper
private readonly FilesLinkUtility _filesLinkUtility;
private readonly FileUtility _fileUtility;
private readonly BadgesSettingsHelper _badgesSettingsHelper;
private readonly ExternalShare _externalShare;

public FileDtoHelper(
ApiDateTimeHelper apiDateTimeHelper,
Expand All @@ -159,7 +160,8 @@ public FileDtoHelper(
FileSharingHelper fileSharingHelper,
BadgesSettingsHelper badgesSettingsHelper,
FilesSettingsHelper filesSettingsHelper,
FileDateTime fileDateTime)
FileDateTime fileDateTime,
ExternalShare externalShare)
: base(apiDateTimeHelper, employeeWrapperHelper, fileSharingHelper, fileSecurity, globalFolderHelper, filesSettingsHelper, fileDateTime)
{
_authContext = authContext;
Expand All @@ -169,6 +171,7 @@ public FileDtoHelper(
_filesLinkUtility = filesLinkUtility;
_fileUtility = fileUtility;
_badgesSettingsHelper = badgesSettingsHelper;
_externalShare = externalShare;
}

public async Task<FileDto<T>> GetAsync<T>(File<T> file, List<Tuple<FileEntry<T>, bool>> folders = null)
Expand Down Expand Up @@ -228,17 +231,17 @@ private async Task<FileDto<T>> GetFileWrapperAsync<T>(File<T> file)

try
{
result.ViewUrl = _commonLinkUtility.GetFullAbsolutePath(file.DownloadUrl);
result.ViewUrl = _externalShare.GetUrlWithShare(_commonLinkUtility.GetFullAbsolutePath(file.DownloadUrl));

result.WebUrl = _commonLinkUtility.GetFullAbsolutePath(_filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, file.Title, file.Id, file.Version));
result.WebUrl = _externalShare.GetUrlWithShare(_commonLinkUtility.GetFullAbsolutePath(_filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, file.Title, file.Id, file.Version)));

result.ThumbnailStatus = file.ThumbnailStatus;

var cacheKey = Math.Abs(result.Updated.GetHashCode());

if (file.ThumbnailStatus == Thumbnail.Created)
{
result.ThumbnailUrl = _commonLinkUtility.GetFullAbsolutePath(_filesLinkUtility.GetFileThumbnailUrl(file.Id, file.Version)) + $"&hash={cacheKey}";
result.ThumbnailUrl = _externalShare.GetUrlWithShare(_commonLinkUtility.GetFullAbsolutePath(_filesLinkUtility.GetFileThumbnailUrl(file.Id, file.Version)) + $"&hash={cacheKey}");
}
}
catch (Exception)
Expand Down
18 changes: 18 additions & 0 deletions products/ASC.Files/Core/Core/FileStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2539,6 +2539,24 @@ public async Task<AceWrapper> GetPrimaryExternalLinkAsync<T>(T entryId, FileEntr

entry.NotFoundIfNull();

if (entry.FileEntryType == FileEntryType.File && entry.RootFolderType == FolderType.VirtualRooms)
{
var room = await _daoFactory.GetFolderDao<T>().GetParentFoldersAsync(entry.ParentId).
FirstOrDefaultAsync(f => DocSpaceHelper.IsRoom(f.FolderType));

var parentLink = await _fileSharing.GetPureSharesAsync(room, ShareFilterType.PrimaryExternalLink, null, 0, 1)
.FirstOrDefaultAsync();
if (parentLink == null)
{
return null;
}

var data = await _externalShare.GetLinkDataAsync(entry, parentLink.Id);
parentLink.Link = await _urlShortener.GetShortenLinkAsync(data.Url);

return parentLink;
}

var link = await _fileSharing.GetPureSharesAsync(entry, ShareFilterType.PrimaryExternalLink, null, 0, 1)
.FirstOrDefaultAsync();

Expand Down
51 changes: 47 additions & 4 deletions products/ASC.Files/Core/Core/Security/ExternalShare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class ExternalShare
private readonly CookiesManager _cookiesManager;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly FileUtility _fileUtility;
private Guid _linkId;
private Guid _sessionId;
private string _passwordKey;
Expand All @@ -44,22 +46,41 @@ public ExternalShare(
IDaoFactory daoFactory,
CookiesManager cookiesManager,
IHttpContextAccessor httpContextAccessor,
CommonLinkUtility commonLinkUtility)
CommonLinkUtility commonLinkUtility,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility)
{
_global = global;
_daoFactory = daoFactory;
_cookiesManager = cookiesManager;
_httpContextAccessor = httpContextAccessor;
_commonLinkUtility = commonLinkUtility;
_filesLinkUtility = filesLinkUtility;
_fileUtility = fileUtility;
}

public async Task<LinkData> GetLinkDataAsync(Guid linkId)
public async Task<LinkData> GetLinkDataAsync<T>(FileEntry<T> entry, Guid linkId)
{
var key = await CreateShareKeyAsync(linkId);
string url = null;

switch (entry)
{
case File<T> file:
url = _fileUtility.CanWebView(file.Title)
? _filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, file.Title, file.Id)
: file.DownloadUrl;

url += $"&{FilesLinkUtility.ShareKey}={key}";
break;
case Folder<T> folder when DocSpaceHelper.IsRoom(folder.FolderType):
url = $"rooms/share?key={key}";
break;
}

return new LinkData
{
Url = _commonLinkUtility.GetFullAbsolutePath($"rooms/share?key={key}"),
Url = _commonLinkUtility.GetFullAbsolutePath(url),
Token = key
};
}
Expand Down Expand Up @@ -134,7 +155,7 @@ public string GetKey()

if (string.IsNullOrEmpty(key))
{
key = _httpContextAccessor.HttpContext?.Request.Query.GetRequestValue(FilesLinkUtility.FolderShareKey);
key = _httpContextAccessor.HttpContext?.Request.Query.GetRequestValue(FilesLinkUtility.ShareKey);
}

return string.IsNullOrEmpty(key) ? null : key;
Expand Down Expand Up @@ -267,6 +288,28 @@ public async Task SetAnonymousSessionKeyAsync()
await _cookiesManager.SetCookiesAsync(CookiesType.AnonymousSessionKey, Signature.Create(Guid.NewGuid(), await GetDbKeyAsync()), true);
}

public string GetUrlWithShare(string url, string key = null)
{
if (string.IsNullOrEmpty(url))
{
return url;
}

key ??= GetKey();

if (string.IsNullOrEmpty(key))
{
return url;
}

var uriBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query[FilesLinkUtility.ShareKey] = key;
uriBuilder.Query = query.ToString() ?? string.Empty;

return uriBuilder.ToString();
}

private async Task<string> CreateShareKeyAsync(Guid linkId)
{
return Signature.Create(linkId, await GetDbKeyAsync());
Expand Down
43 changes: 7 additions & 36 deletions products/ASC.Files/Core/Helpers/FilesLinkUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,21 @@ public class FilesLinkUtility
private readonly CoreSettings _coreSettings;
private readonly IConfiguration _configuration;
private readonly InstanceCrypto _instanceCrypto;
private readonly ExternalShare _externalShare;

public FilesLinkUtility(
CommonLinkUtility commonLinkUtility,
BaseCommonLinkUtility baseCommonLinkUtility,
CoreBaseSettings coreBaseSettings,
CoreSettings coreSettings,
IConfiguration configuration,
InstanceCrypto instanceCrypto,
ExternalShare externalShare)
InstanceCrypto instanceCrypto)
{
_commonLinkUtility = commonLinkUtility;
_baseCommonLinkUtility = baseCommonLinkUtility;
_coreBaseSettings = coreBaseSettings;
_coreSettings = coreSettings;
_configuration = configuration;
_instanceCrypto = instanceCrypto;
_externalShare = externalShare;
_filesUploaderURL = _configuration["files:uploader:url"] ?? "~";
}

Expand All @@ -78,7 +75,7 @@ public string FilesBaseAbsolutePath
public const string AuthKey = "stream_auth";
public const string Anchor = "anchor";
public const string Size = "size";
public const string FolderShareKey = "share";
public const string ShareKey = "share";

public string FileHandlerPath
{
Expand Down Expand Up @@ -289,18 +286,14 @@ public string GetFileDownloadUrl(object fileId)

public string GetFileDownloadUrl(object fileId, int fileVersion, string convertToExtension)
{
var url = string.Format(FileDownloadUrlString, HttpUtility.UrlEncode(fileId.ToString()))
return string.Format(FileDownloadUrlString, HttpUtility.UrlEncode(fileId.ToString()))
+ (fileVersion > 0 ? "&" + Version + "=" + fileVersion : string.Empty)
+ (string.IsNullOrEmpty(convertToExtension) ? string.Empty : "&" + OutType + "=" + convertToExtension);

return GetUrlWithShare(url);
}

public string GetFileWebMediaViewUrl(object fileId)
{
var url = FilesBaseAbsolutePath + "#preview/" + HttpUtility.UrlEncode(fileId.ToString());

return GetUrlWithShare(url);
return FilesBaseAbsolutePath + "#preview/" + HttpUtility.UrlEncode(fileId.ToString());
}

public string FileWebViewerUrlString
Expand All @@ -320,10 +313,8 @@ public string FileWebEditorUrlString

public string GetFileWebEditorUrl<T>(T fileId, int fileVersion = 0)
{
var url = string.Format(FileWebEditorUrlString, HttpUtility.UrlEncode(fileId.ToString()))
return string.Format(FileWebEditorUrlString, HttpUtility.UrlEncode(fileId.ToString()))
+ (fileVersion > 0 ? "&" + Version + "=" + fileVersion : string.Empty);

return GetUrlWithShare(url);
}

public string GetFileWebEditorTryUrl(FileType fileType)
Expand Down Expand Up @@ -363,8 +354,7 @@ public string GetFileWebPreviewUrl(FileUtility fileUtility, string fileTitle, ob
{
if (fileUtility.ExtsMustConvert.Contains(FileUtility.GetFileExtension(fileTitle)))
{
var url = string.Format(FileWebViewerUrlString, HttpUtility.UrlEncode(fileId.ToString()));
return GetUrlWithShare(url);
return string.Format(FileWebViewerUrlString, HttpUtility.UrlEncode(fileId.ToString()));
}

return GetFileWebEditorUrl(fileId, fileVersion);
Expand All @@ -390,10 +380,8 @@ public string FileThumbnailUrlString

public string GetFileThumbnailUrl(object fileId, int fileVersion)
{
var url = string.Format(FileThumbnailUrlString, HttpUtility.UrlEncode(fileId.ToString()))
return string.Format(FileThumbnailUrlString, HttpUtility.UrlEncode(fileId.ToString()))
+ (fileVersion > 0 ? "&" + Version + "=" + fileVersion : string.Empty);

return GetUrlWithShare(url);
}


Expand Down Expand Up @@ -493,21 +481,4 @@ private string GetSettingsKey(string key)
{
return "DocKey_" + key;
}

private string GetUrlWithShare(string url)
{
if (_externalShare.GetLinkId() == Guid.Empty)
{
return url;
}

var key = _externalShare.GetKey();

if (!string.IsNullOrEmpty(key))
{
url += $"&{FolderShareKey}={key}";
}

return url;
}
}
2 changes: 1 addition & 1 deletion products/ASC.Files/Core/HttpHandlers/FileHandler.ashx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ private async Task StreamFileAsync<T>(HttpContext context, T id)
version = 0;
}
var doc = context.Request.Query[FilesLinkUtility.DocShareKey];
var share = context.Request.Query[FilesLinkUtility.FolderShareKey];
var share = context.Request.Query[FilesLinkUtility.ShareKey];

await fileDao.InvalidateCacheAsync(id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ public DocumentServiceHelper(
return (file, configuration, locatedInPrivateRoom);
}

configuration.Document.SharedLinkParam = FilesLinkUtility.FolderShareKey;
configuration.Document.SharedLinkParam = FilesLinkUtility.ShareKey;
configuration.Document.SharedLinkKey = _externalShare.GetKey();

return (file, configuration, locatedInPrivateRoom);
Expand Down
6 changes: 3 additions & 3 deletions products/ASC.Files/Core/Utils/FileSharing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ public async Task<List<AceWrapper>> GetSharedInfoAsync<T>(FileEntry<T> entry, IE

var link = r.SubjectType == SubjectType.InvitationLink
? _invitationLinkService.GetInvitationLink(r.Subject, _authContext.CurrentAccount.ID)
: (await _externalShare.GetLinkDataAsync(r.Subject)).Url;
: (await _externalShare.GetLinkDataAsync(entry, r.Subject)).Url;

w.Link = await _urlShortener.GetShortenLinkAsync(link);
w.SubjectGroup = true;
Expand Down Expand Up @@ -949,7 +949,7 @@ private async IAsyncEnumerable<AceWrapper> GetDefaultAcesAsync<T>(FileEntry<T> e
yield return owner;
}

private async Task<AceWrapper> ToAceAsync(FileEntry entry, FileShareRecord record, bool canEditAccess)
private async Task<AceWrapper> ToAceAsync<T>(FileEntry<T> entry, FileShareRecord record, bool canEditAccess)
{
var w = new AceWrapper
{
Expand Down Expand Up @@ -983,7 +983,7 @@ private async Task<AceWrapper> ToAceAsync(FileEntry entry, FileShareRecord recor
}
else
{
var linkData = await _externalShare.GetLinkDataAsync(record.Subject);
var linkData = await _externalShare.GetLinkDataAsync(entry, record.Subject);
link = linkData.Url;
w.RequestToken = linkData.Token;
}
Expand Down
Loading

0 comments on commit be6a206

Please sign in to comment.