[wopi] Fix downloadfile handler for wopi; fix bug 66612

# Conflicts:
#	DocService/sources/canvasservice.js
#	DocService/sources/wopiClient.js
This commit is contained in:
Sergey Konovalov
2024-02-26 14:09:00 +03:00
parent 69ff2f3e92
commit fb7b1c4257
4 changed files with 33 additions and 20 deletions

View File

@ -2242,7 +2242,7 @@ exports.install = function(server, callbackFunction) {
let queryParams = decoded.queryParams;
data.lang = queryParams.lang || queryParams.ui || "en-US";
}
if (decoded.fileInfo) {
if (wopiClient.isWopiJwtToken(decoded)) {
let fileInfo = decoded.fileInfo;
if (openCmd) {
openCmd.format = wopiClient.getFileTypeByInfo(fileInfo);
@ -2397,7 +2397,7 @@ exports.install = function(server, callbackFunction) {
}
//todo make required fields
if (decoded.url || decoded.payload|| (decoded.key && !decoded.fileInfo)) {
if (decoded.url || decoded.payload|| (decoded.key && !wopiClient.isWopiJwtToken(decoded))) {
ctx.logger.warn('fillDataFromJwt token has invalid format');
res = false;
}
@ -2438,7 +2438,7 @@ exports.install = function(server, callbackFunction) {
isDecoded = true;
let decoded = checkJwtRes.decoded;
let fillDataFromJwtRes = false;
if (decoded.fileInfo) {
if (wopiClient.isWopiJwtToken(decoded)) {
//wopi
fillDataFromJwtRes = fillDataFromWopiJwt(decoded, data);
} else if (decoded.editorConfig && undefined !== decoded.editorConfig.ds_view) {

View File

@ -1598,6 +1598,7 @@ exports.downloadFile = function(req, res) {
let authorization;
let isInJwtToken = false;
let errorDescription;
let headers;
let authRes = yield docsCoServer.getRequestParams(ctx, req);
if (authRes.code === constants.NO_ERROR) {
let decoded = authRes.params;
@ -1610,6 +1611,8 @@ exports.downloadFile = function(req, res) {
} else if (decoded.url && -1 !== tenDownloadFileAllowExt.indexOf(decoded.fileType)) {
url = decoded.url;
isInJwtToken = true;
} else if (wopiClient.isWopiJwtToken(decoded)) {
({url, headers} = wopiClient.getWopiFileUrl(ctx, decoded.fileInfo, decoded.userAuth));
} else if (!tenTokenEnableBrowser) {
//todo token required
if (decoded.url) {
@ -1638,11 +1641,12 @@ exports.downloadFile = function(req, res) {
res.sendStatus(filterStatus);
return;
}
let headers;
if (req.get('Range')) {
headers = {
'Range': req.get('Range')
if (!headers) {
headers = {};
}
headers['Range'] = req.get('Range');
}
yield utils.downloadUrlPromise(ctx, url, tenDownloadTimeout, tenDownloadMaxBytes, authorization, isInJwtToken, headers, res);

View File

@ -63,6 +63,7 @@ const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.brow
const cfgCallbackRequestTimeout = config.get('services.CoAuthoring.server.callbackRequestTimeout');
const cfgNewFileTemplate = config.get('services.CoAuthoring.server.newFileTemplate');
const cfgDownloadTimeout = config.get('FileConverter.converter.downloadTimeout');
const cfgMaxDownloadBytes = config.get('FileConverter.converter.maxDownloadBytes');
const cfgWopiFileInfoBlockList = config.get('wopi.fileInfoBlockList');
const cfgWopiWopiZone = config.get('wopi.wopiZone');
const cfgWopiPdfView = config.get('wopi.pdfView');
@ -289,6 +290,25 @@ function getFileTypeByInfo(fileInfo) {
fileType = fileInfo.FileExtension ? fileInfo.FileExtension.substr(1) : fileType;
return fileType.toLowerCase();
}
function getWopiFileUrl(ctx, fileInfo, userAuth) {
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
let url;
let headers = {'X-WOPI-MaxExpectedSize': tenMaxDownloadBytes};
if (fileInfo?.FileUrl) {
//Requests to the FileUrl can not be signed using proof keys. The FileUrl is used exactly as provided by the host, so it does not necessarily include the access token, which is required to construct the expected proof.
url = fileInfo.FileUrl;
} else if (fileInfo?.TemplateSource) {
url = fileInfo.TemplateSource;
} else if (userAuth) {
url = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
fillStandardHeaders(ctx, headers, url, userAuth.access_token);
}
ctx.logger.debug('getWopiFileUrl url=%s; headers=%j', url, headers);
return {url, headers};
}
function isWopiJwtToken(decoded) {
return !!decoded.fileInfo;
}
function getLastModifiedTimeFromCallbacks(callbacks) {
for (let i = callbacks.length; i >= 0; --i) {
let callback = callbacks[i];
@ -952,6 +972,8 @@ exports.fillStandardHeaders = fillStandardHeaders;
exports.getWopiUnlockMarker = getWopiUnlockMarker;
exports.getWopiModifiedMarker = getWopiModifiedMarker;
exports.getFileTypeByInfo = getFileTypeByInfo;
exports.getWopiFileUrl = getWopiFileUrl;
exports.isWopiJwtToken = isWopiJwtToken;
exports.dummyCheckFileInfo = dummyCheckFileInfo;
exports.dummyGetFile = dummyGetFile;
exports.dummyOk = dummyOk;

View File

@ -429,7 +429,6 @@ function* downloadFile(ctx, uri, fileFrom, withAuthorization, isInJwtToken, opt_
return res;
}
function* downloadFileFromStorage(ctx, strPath, dir, opt_specialDir) {
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
var list = yield storage.listObjects(ctx, strPath, opt_specialDir);
ctx.logger.debug('downloadFileFromStorage list %s', list.toString());
//create dirs
@ -1002,7 +1001,6 @@ function* spawnProcess(ctx, builderParams, tempDirs, dataConvert, authorProps, g
}
function* ExecuteTask(ctx, task) {
const tenMaxDownloadBytes = ctx.getCfg('FileConverter.converter.maxDownloadBytes', cfgMaxDownloadBytes);
const tenForgottenFiles = ctx.getCfg('services.CoAuthoring.server.forgottenfiles', cfgForgottenFiles);
const tenForgottenFilesName = ctx.getCfg('services.CoAuthoring.server.forgottenfilesname', cfgForgottenFilesName);
var startDate = null;
@ -1039,19 +1037,8 @@ function* ExecuteTask(ctx, task) {
withAuthorization = false;
isInJwtToken = true;
let fileInfo = wopiParams.commonInfo?.fileInfo;
let userAuth = wopiParams.userAuth;
fileSize = fileInfo?.Size;
if (fileInfo?.FileUrl) {
//Requests to the FileUrl can not be signed using proof keys. The FileUrl is used exactly as provided by the host, so it does not necessarily include the access token, which is required to construct the expected proof.
url = fileInfo.FileUrl;
} else if (fileInfo?.TemplateSource) {
url = fileInfo.TemplateSource;
} else if (userAuth) {
url = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
headers = {'X-WOPI-MaxExpectedSize': tenMaxDownloadBytes};
wopiClient.fillStandardHeaders(ctx, headers, url, userAuth.access_token);
}
ctx.logger.debug('wopi url=%s; headers=%j', url, headers);
({url, headers} = wopiClient.getWopiFileUrl(ctx, fileInfo, wopiParams.userAuth));
}
if (undefined === fileSize || fileSize > 0) {
error = yield* downloadFile(ctx, url, dataConvert.fileFrom, withAuthorization, isInJwtToken, headers);