Skip to content

Commit

Permalink
[wopi] Fix downloadfile handler for wopi; fix bug 66612
Browse files Browse the repository at this point in the history
# Conflicts:
#	DocService/sources/canvasservice.js
#	DocService/sources/wopiClient.js
  • Loading branch information
konovalovsergey committed Feb 26, 2024
1 parent 69ff2f3 commit fb7b1c4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
6 changes: 3 additions & 3 deletions DocService/sources/DocsCoServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 7 additions & 3 deletions DocService/sources/canvasservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 22 additions & 0 deletions DocService/sources/wopiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;
15 changes: 1 addition & 14 deletions FileConverter/sources/converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fb7b1c4

Please sign in to comment.