Skip to content

Commit

Permalink
Merge pull request 'Bugfix/70215' (#32) from bugfix/70215 into hotfix…
Browse files Browse the repository at this point in the history
…/v2.6.3

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/DocSpace-server/pulls/32
Reviewed-by: Nikolay Rechkin <[email protected]>
  • Loading branch information
NikolayRechkin committed Oct 1, 2024
2 parents 4858b5f + ccf3c5a commit 8adabbf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public async Task<EditorConfigurationDto<T>> Convert(Configuration<T> configurat
var fileType = configuration.GetFileType(file);
var result = new EditorConfigurationDto<T>
{
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
57 changes: 46 additions & 11 deletions products/ASC.Files/Core/Core/Security/ExternalShare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public class ExternalShare(Global global,
IHttpContextAccessor httpContextAccessor,
BaseCommonLinkUtility commonLinkUtility,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility,
ILogger<ExternalShare> logger)
FileUtility fileUtility)
{
private ExternalSessionSnapshot _snapshot;
private string _dbKey;
Expand Down Expand Up @@ -122,9 +121,17 @@ public async Task<Status> ValidateRecordAsync<T>(FileShareRecord<T> 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;
Expand Down Expand Up @@ -169,11 +176,22 @@ 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());

var stringKey = Signature.Read<string>(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<TokenData>(stringKey);
return token;
}

public async Task<Guid> GetLinkIdAsync()
Expand All @@ -189,8 +207,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 @@ -277,9 +295,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 @@ -374,4 +403,10 @@ public enum Status
RequiredPassword,
InvalidPassword,
ExternalAccessDenied
}

public record TokenData
{
public Guid Id { get; set; }
public string Password { get; set; }
}
8 changes: 3 additions & 5 deletions products/ASC.Files/Core/Helpers/ExternalLinkHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@ 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(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;
}

Expand All @@ -54,7 +53,6 @@ public async Task<ValidationInfo> 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;
}

Expand Down Expand Up @@ -91,7 +89,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
16 changes: 12 additions & 4 deletions products/ASC.Files/Core/Services/DocumentService/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,26 @@ public async Task<UserConfig> GetUserAsync()
return _user;
}

public async Task<string> GetCallbackUrl(string fileId, string fillingSessionId)
public async Task<string> GetCallbackUrl(File<T> 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<CoEditingConfig> GetCoEditingAsync()
Expand Down

0 comments on commit 8adabbf

Please sign in to comment.