From 74332adb5a468d0258012ec78d3dc5edbfd2c8b1 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 24 Jul 2023 13:33:10 +0300 Subject: [PATCH] [feature] Use ctx.getCfg in utils --- Common/sources/storage-base.js | 6 +- Common/sources/storage-fs.js | 4 +- Common/sources/storage-s3.js | 2 +- Common/sources/utils.js | 162 ++++++++++++++---------- DocService/sources/DocsCoServer.js | 12 +- DocService/sources/canvasservice.js | 10 +- DocService/sources/changes2forgotten.js | 2 +- DocService/sources/converterservice.js | 10 +- DocService/sources/shutdown.js | 2 +- DocService/sources/wopiClient.js | 10 +- FileConverter/sources/converter.js | 37 +++--- 11 files changed, 144 insertions(+), 113 deletions(-) diff --git a/Common/sources/storage-base.js b/Common/sources/storage-base.js index b734a644..a99d4ca3 100644 --- a/Common/sources/storage-base.js +++ b/Common/sources/storage-base.js @@ -101,13 +101,13 @@ exports.deletePath = function(ctx, strPath, opt_specialDir) { }); }; exports.getSignedUrl = function(ctx, baseUrl, strPath, urlType, optFilename, opt_creationDate, opt_specialDir) { - return storage.getSignedUrl(baseUrl, getStoragePath(ctx, strPath, opt_specialDir), urlType, optFilename, opt_creationDate); + return storage.getSignedUrl(ctx, baseUrl, getStoragePath(ctx, strPath, opt_specialDir), urlType, optFilename, opt_creationDate); }; exports.getSignedUrls = function(ctx, baseUrl, strPath, urlType, opt_creationDate, opt_specialDir) { let storageSrc = getStoragePath(ctx, strPath, opt_specialDir); return storage.listObjects(storageSrc).then(function(list) { return Promise.all(list.map(function(curValue) { - return storage.getSignedUrl(baseUrl, curValue, urlType, undefined, opt_creationDate); + return storage.getSignedUrl(ctx, baseUrl, curValue, urlType, undefined, opt_creationDate); })).then(function(urls) { var outputMap = {}; for (var i = 0; i < list.length && i < urls.length; ++i) { @@ -120,7 +120,7 @@ exports.getSignedUrls = function(ctx, baseUrl, strPath, urlType, opt_creationDat exports.getSignedUrlsArrayByArray = function(ctx, baseUrl, list, urlType, opt_specialDir) { return Promise.all(list.map(function(curValue) { let storageSrc = getStoragePath(ctx, curValue, opt_specialDir); - return storage.getSignedUrl(baseUrl, storageSrc, urlType, undefined); + return storage.getSignedUrl(ctx, baseUrl, storageSrc, urlType, undefined); })); }; exports.getSignedUrlsByArray = function(ctx, baseUrl, list, optPath, urlType, opt_specialDir) { diff --git a/Common/sources/storage-fs.js b/Common/sources/storage-fs.js index 03af546b..efbfd3ed 100644 --- a/Common/sources/storage-fs.js +++ b/Common/sources/storage-fs.js @@ -180,13 +180,13 @@ exports.deleteObject = function(strPath) { exports.deleteObjects = function(strPaths) { return Promise.all(strPaths.map(exports.deleteObject)); }; -exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_creationDate) { +exports.getSignedUrl = function(ctx, baseUrl, strPath, urlType, optFilename, opt_creationDate) { return new Promise(function(resolve, reject) { //replace '/' with %2f before encodeURIComponent becase nginx determine %2f as '/' and get wrong system path var userFriendlyName = optFilename ? encodeURIComponent(optFilename.replace(/\//g, "%2f")) : path.basename(strPath); var uri = '/' + cfgBucketName + '/' + cfgStorageFolderName + '/' + strPath + '/' + userFriendlyName; //RFC 1123 does not allow underscores https://stackoverflow.com/questions/2180465/can-domain-name-subdomains-have-an-underscore-in-it - var url = utils.checkBaseUrl(baseUrl).replace(/_/g, "%5f"); + var url = utils.checkBaseUrl(ctx, baseUrl).replace(/_/g, "%5f"); url += uri; var date = Date.now(); diff --git a/Common/sources/storage-s3.js b/Common/sources/storage-s3.js index 72a334e2..e288a802 100644 --- a/Common/sources/storage-s3.js +++ b/Common/sources/storage-s3.js @@ -206,7 +206,7 @@ exports.deleteObjects = function(strPaths) { } return Promise.all(deletePromises); }; -exports.getSignedUrl = async function (baseUrl, strPath, urlType, optFilename, opt_creationDate) { +exports.getSignedUrl = async function (ctx, baseUrl, strPath, urlType, optFilename, opt_creationDate) { var expires = (commonDefines.c_oAscUrlTypes.Session === urlType ? cfgExpSessionAbsolute / 1000 : cfgStorageUrlExpires) || 31536000; // Signature version 4 presigned URLs must have an expiration date less than one week in the future expires = Math.min(expires, 604800); diff --git a/Common/sources/utils.js b/Common/sources/utils.js index 0ba80f68..d5e49325 100644 --- a/Common/sources/utils.js +++ b/Common/sources/utils.js @@ -45,12 +45,7 @@ var co = require('co'); var URI = require("uri-js"); const escapeStringRegexp = require('escape-string-regexp'); const ipaddr = require('ipaddr.js'); -var configDnsCache = config.get('dnscache'); -const dnscache = require('dnscache')({ - "enable": configDnsCache.get('enable'), - "ttl": configDnsCache.get('ttl'), - "cachesize": configDnsCache.get('cachesize') - }); +const getDnsCache = require('dnscache'); const jwt = require('jsonwebtoken'); const NodeCache = require( "node-cache" ); const ms = require('ms'); @@ -68,58 +63,62 @@ if(!ca.disabled) { } const contentDisposition = require('content-disposition'); +const operationContext = require("./operationContext"); -var configIpFilter = config.get('services.CoAuthoring.ipfilter'); -var cfgIpFilterRules = configIpFilter.get('rules'); -var cfgIpFilterErrorCode = configIpFilter.get('errorcode'); -const cfgIpFilterUseForRequest = configIpFilter.get('useforrequest'); -var cfgExpPemStdTtl = config.get('services.CoAuthoring.expire.pemStdTTL'); -var cfgExpPemCheckPeriod = config.get('services.CoAuthoring.expire.pemCheckPeriod'); -var cfgTokenOutboxHeader = config.get('services.CoAuthoring.token.outbox.header'); -var cfgTokenOutboxPrefix = config.get('services.CoAuthoring.token.outbox.prefix'); -var cfgTokenOutboxAlgorithm = config.get('services.CoAuthoring.token.outbox.algorithm'); -var cfgTokenOutboxExpires = config.get('services.CoAuthoring.token.outbox.expires'); -var cfgVisibilityTimeout = config.get('queue.visibilityTimeout'); -var cfgQueueRetentionPeriod = config.get('queue.retentionPeriod'); -var cfgRequestDefaults = config.get('services.CoAuthoring.requestDefaults'); +const cfgDnsCache = config.get('dnscache'); +const cfgIpFilterRules = config.get('services.CoAuthoring.ipfilter.rules'); +const cfgIpFilterErrorCode = config.get('services.CoAuthoring.ipfilter.errorcode'); +const cfgIpFilterUseForRequest = config.get('services.CoAuthoring.ipfilter.useforrequest'); +const cfgExpPemStdTtl = config.get('services.CoAuthoring.expire.pemStdTTL'); +const cfgExpPemCheckPeriod = config.get('services.CoAuthoring.expire.pemCheckPeriod'); +const cfgTokenOutboxHeader = config.get('services.CoAuthoring.token.outbox.header'); +const cfgTokenOutboxPrefix = config.get('services.CoAuthoring.token.outbox.prefix'); +const cfgTokenOutboxAlgorithm = config.get('services.CoAuthoring.token.outbox.algorithm'); +const cfgTokenOutboxExpires = config.get('services.CoAuthoring.token.outbox.expires'); +const cfgVisibilityTimeout = config.get('queue.visibilityTimeout'); +const cfgQueueRetentionPeriod = config.get('queue.retentionPeriod'); +const cfgRequestDefaults = config.get('services.CoAuthoring.requestDefaults'); const cfgTokenEnableRequestOutbox = config.get('services.CoAuthoring.token.enable.request.outbox'); const cfgTokenOutboxUrlExclusionRegex = config.get('services.CoAuthoring.token.outbox.urlExclusionRegex'); const cfgPasswordEncrypt = config.get('openpgpjs.encrypt'); const cfgPasswordDecrypt = config.get('openpgpjs.decrypt'); const cfgPasswordConfig = config.get('openpgpjs.config'); -const cfgRequesFilteringAgent = Object.assign({}, https.globalAgent.options, config.get('services.CoAuthoring.request-filtering-agent')); +const cfgRequesFilteringAgent = config.get('services.CoAuthoring.request-filtering-agent'); const cfgStorageExternalHost = config.get('storage.externalHost'); -Object.assign(openpgp.config, cfgPasswordConfig); +const dnscache = getDnsCache(cfgDnsCache); var ANDROID_SAFE_FILENAME = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-+,@£$€!½§~\'=()[]{}0123456789'; //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json BigInt.prototype.toJSON = function() { return this.toString() }; -var baseRequest = request.defaults(cfgRequestDefaults); -let outboxUrlExclusionRegex = null; -if ("" !== cfgTokenOutboxUrlExclusionRegex) { - outboxUrlExclusionRegex = new RegExp(cfgTokenOutboxUrlExclusionRegex); -} - -var g_oIpFilterRules = function() { +var g_oIpFilterRules = new Map(); +function getIpFilterRules(rules) { var res = []; - for (var i = 0; i < cfgIpFilterRules.length; ++i) { - var rule = cfgIpFilterRules[i]; + for (var i = 0; i < rules.length; ++i) { + var rule = rules[i]; var regExpStr = rule['address'].split('*').map(escapeStringRegexp).join('.*'); var exp = new RegExp('^' + regExpStr + '$', 'i'); res.push({allow: rule['allowed'], exp: exp}); } return res; -}(); +} const pemfileCache = new NodeCache({stdTTL: ms(cfgExpPemStdTtl) / 1000, checkperiod: ms(cfgExpPemCheckPeriod) / 1000, errorOnMissing: false, useClones: true}); function getRequestFilterAgent(url, options) { return url.startsWith("https") ? new RequestFilteringHttpsAgent(options) : new RequestFilteringHttpAgent(options); } -exports.CONVERTION_TIMEOUT = 1.5 * (cfgVisibilityTimeout + cfgQueueRetentionPeriod) * 1000; +exports.getConvertionTimeout = function(opt_ctx) { + if (opt_ctx) { + const tenVisibilityTimeout = ctx.getCfg('queue.visibilityTimeout', cfgVisibilityTimeout); + const tenQueueRetentionPeriod = ctx.getCfg('queue.retentionPeriod', cfgQueueRetentionPeriod); + return 1.5 * (tenVisibilityTimeout + tenQueueRetentionPeriod) * 1000; + } else { + return 1.5 * (cfgVisibilityTimeout + cfgQueueRetentionPeriod) * 1000; + } +} exports.addSeconds = function(date, sec) { date.setSeconds(date.getSeconds() + sec); @@ -269,9 +268,9 @@ function isRedirectResponse(response) { } function downloadUrlPromise(ctx, uri, optTimeout, optLimit, opt_Authorization, opt_filterPrivate, opt_headers, opt_streamWriter) { //todo replace deprecated request module - const cfgTenantRequestDefaults = ctx.getCfg('services.CoAuthoring.requestDefaults', cfgRequestDefaults); - const maxRedirects = (undefined !== cfgTenantRequestDefaults.maxRedirects) ? cfgTenantRequestDefaults.maxRedirects : 10; - const followRedirect = (undefined !== cfgTenantRequestDefaults.followRedirect) ? cfgTenantRequestDefaults.followRedirect : true; + const tenTenantRequestDefaults = ctx.getCfg('services.CoAuthoring.requestDefaults', cfgRequestDefaults); + const maxRedirects = (undefined !== tenTenantRequestDefaults.maxRedirects) ? tenTenantRequestDefaults.maxRedirects : 10; + const followRedirect = (undefined !== tenTenantRequestDefaults.followRedirect) ? tenTenantRequestDefaults.followRedirect : true; var redirectsFollowed = 0; let doRequest = function(curUrl) { return downloadUrlPromiseWithoutRedirect(ctx, curUrl, optTimeout, optLimit, opt_Authorization, opt_filterPrivate, opt_headers, opt_streamWriter) @@ -296,6 +295,10 @@ function downloadUrlPromise(ctx, uri, optTimeout, optLimit, opt_Authorization, o } function downloadUrlPromiseWithoutRedirect(ctx, uri, optTimeout, optLimit, opt_Authorization, opt_filterPrivate, opt_headers, opt_streamWriter) { return new Promise(function (resolve, reject) { + const tenTenantRequestDefaults = ctx.getCfg('services.CoAuthoring.requestDefaults', cfgRequestDefaults); + const tenTokenOutboxHeader = ctx.getCfg('services.CoAuthoring.token.outbox.header', cfgTokenOutboxHeader); + const tenTokenOutboxPrefix = ctx.getCfg('services.CoAuthoring.token.outbox.prefix', cfgTokenOutboxPrefix); + const tenRequesFilteringAgent = ctx.getCfg('services.CoAuthoring.request-filtering-agent', cfgRequesFilteringAgent); //IRI to URI uri = URI.serialize(URI.parse(uri)); var urlParsed = url.parse(uri); @@ -304,19 +307,18 @@ function downloadUrlPromiseWithoutRedirect(ctx, uri, optTimeout, optLimit, opt_A let hash = crypto.createHash('sha256'); //if you expect binary data, you should set encoding: null let connectionAndInactivity = optTimeout && optTimeout.connectionAndInactivity && ms(optTimeout.connectionAndInactivity); - var options = {uri: urlParsed, encoding: null, timeout: connectionAndInactivity, followRedirect: false}; + let options = config.util.extendDeep({}, tenTenantRequestDefaults); + Object.assign(options, {uri: urlParsed, encoding: null, timeout: connectionAndInactivity, followRedirect: false}); if (opt_filterPrivate) { - //todo ctx.getCfg - options.agent = getRequestFilterAgent(uri, cfgRequesFilteringAgent); + const options = Object.assign({}, https.globalAgent.options, tenRequesFilteringAgent); + options.agent = getRequestFilterAgent(uri, options); } else { //baseRequest creates new agent(win-ca injects in globalAgent) options.agentOptions = https.globalAgent.options; } if (opt_Authorization) { - let cfgTenantTokenOutboxHeader = ctx.getCfg('services.CoAuthoring.token.outbox.header', cfgTokenOutboxHeader); - let cfgTenantTokenOutboxPrefix = ctx.getCfg('services.CoAuthoring.token.outbox.prefix', cfgTokenOutboxPrefix); options.headers = {}; - options.headers[cfgTenantTokenOutboxHeader] = cfgTenantTokenOutboxPrefix + opt_Authorization; + options.headers[tenTokenOutboxHeader] = tenTokenOutboxPrefix + opt_Authorization; } if (opt_headers) { options.headers = opt_headers; @@ -378,7 +380,7 @@ function downloadUrlPromiseWithoutRedirect(ctx, uri, optTimeout, optLimit, opt_A } } - let ro = baseRequest.get(options) + let ro = request.get(options) .on('response', fResponse) .on('data', fData) .on('error', fError); @@ -389,15 +391,18 @@ function downloadUrlPromiseWithoutRedirect(ctx, uri, optTimeout, optLimit, opt_A } }); } -function postRequestPromise(uri, postData, postDataStream, postDataSize, optTimeout, opt_Authorization, opt_header) { +function postRequestPromise(ctx, uri, postData, postDataStream, postDataSize, optTimeout, opt_Authorization, opt_header) { return new Promise(function(resolve, reject) { + const tenTenantRequestDefaults = ctx.getCfg('services.CoAuthoring.requestDefaults', cfgRequestDefaults); + const tenTokenOutboxHeader = ctx.getCfg('services.CoAuthoring.token.outbox.header', cfgTokenOutboxHeader); + const tenTokenOutboxPrefix = ctx.getCfg('services.CoAuthoring.token.outbox.prefix', cfgTokenOutboxPrefix); //IRI to URI uri = URI.serialize(URI.parse(uri)); var urlParsed = url.parse(uri); var headers = {'Content-Type': 'application/json'}; if (opt_Authorization) { //todo ctx.getCfg - headers[cfgTokenOutboxHeader] = cfgTokenOutboxPrefix + opt_Authorization; + headers[tenTokenOutboxHeader] = tenTokenOutboxPrefix + opt_Authorization; } headers = opt_header || headers; if (undefined !== postDataSize) { @@ -409,7 +414,8 @@ function postRequestPromise(uri, postData, postDataStream, postDataSize, optTime headers['Content-Length'] = postDataSize; } let connectionAndInactivity = optTimeout && optTimeout.connectionAndInactivity && ms(optTimeout.connectionAndInactivity); - var options = {uri: urlParsed, encoding: 'utf8', headers: headers, timeout: connectionAndInactivity}; + let options = config.util.extendDeep({}, tenTenantRequestDefaults); + Object.assign(options, {uri: urlParsed, encoding: 'utf8', headers: headers, timeout: connectionAndInactivity}); //baseRequest creates new agent(win-ca injects in globalAgent) options.agentOptions = https.globalAgent.options; if (postData) { @@ -417,7 +423,7 @@ function postRequestPromise(uri, postData, postDataStream, postDataSize, optTime } let executed = false; - let ro = baseRequest.post(options, function(err, response, body) { + let ro = request.post(options, function(err, response, body) { if (executed) { return; } @@ -784,7 +790,10 @@ function* pipeFiles(from, to) { yield pipeStreams(fromStream, toStream, true); } exports.pipeFiles = co.wrap(pipeFiles); -function checkIpFilter(ipString, opt_hostname) { +function checkIpFilter(ctx, ipString, opt_hostname) { + const tenIpFilterRules = ctx.getCfg('services.CoAuthoring.ipfilter.rules', cfgIpFilterRules); + const tenIpFilterErrorCode = ctx.getCfg('services.CoAuthoring.ipfilter.errorcode', cfgIpFilterErrorCode); + var status = 0; var ip4; var ip6; @@ -800,11 +809,17 @@ function checkIpFilter(ipString, opt_hostname) { ip6 = ip.toIPv4MappedAddress().toNormalizedString(); } } - for (var i = 0; i < g_oIpFilterRules.length; ++i) { - var rule = g_oIpFilterRules[i]; + let ipFilterRules = g_oIpFilterRules.get(ctx.tenant); + if (!ipFilterRules) { + ipFilterRules = getIpFilterRules(tenIpFilterRules); + g_oIpFilterRules.set(ctx.tenant, ipFilterRules); + } + + for (var i = 0; i < ipFilterRules.length; ++i) { + var rule = ipFilterRules[i]; if ((opt_hostname && rule.exp.test(opt_hostname)) || (ip4 && rule.exp.test(ip4)) || (ip6 && rule.exp.test(ip6))) { if (!rule.allow) { - status = cfgIpFilterErrorCode; + status = tenIpFilterErrorCode; } break; } @@ -818,21 +833,25 @@ function* checkHostFilter(ctx, hostname) { try { hostIp = yield dnsLookup(hostname); } catch (e) { - status = cfgIpFilterErrorCode; + const tenIpFilterErrorCode = ctx.getCfg('services.CoAuthoring.ipfilter.errorcode', cfgIpFilterErrorCode); + status = tenIpFilterErrorCode; ctx.logger.error('dnsLookup error: hostname = %s %s', hostname, e.stack); } if (0 === status) { - status = checkIpFilter(hostIp, hostname); + status = checkIpFilter(ctx, hostIp, hostname); } return status; } exports.checkHostFilter = checkHostFilter; function checkClientIp(req, res, next) { + let ctx = new operationContext.Context(); + ctx.initFromRequest(req); + const tenIpFilterUseForRequest = ctx.getCfg('services.CoAuthoring.ipfilter.useforrequest', cfgIpFilterUseForRequest); let status = 0; - if (cfgIpFilterUseForRequest) { + if (tenIpFilterUseForRequest) { const addresses = forwarded(req); const ipString = addresses[addresses.length - 1]; - status = checkIpFilter(ipString); + status = checkIpFilter(ctx, ipString); } if (status > 0) { res.sendStatus(status); @@ -883,7 +902,9 @@ function getSecretByElem(secretElem) { return secret; } exports.getSecretByElem = getSecretByElem; -function fillJwtForRequest(payload, secret, opt_inBody) { +function fillJwtForRequest(ctx, payload, secret, opt_inBody) { + const tenTokenOutboxAlgorithm = ctx.getCfg('services.CoAuthoring.token.outbox.algorithm', cfgTokenOutboxAlgorithm); + const tenTokenOutboxExpires = ctx.getCfg('services.CoAuthoring.token.outbox.expires', cfgTokenOutboxExpires); //todo refuse prototypes in payload(they are simple getter/setter). //JSON.parse/stringify is more universal but Object.assign is enough for our inputs payload = Object.assign(Object.create(null), payload); @@ -894,7 +915,7 @@ function fillJwtForRequest(payload, secret, opt_inBody) { data = {payload: payload}; } - let options = {algorithm: cfgTokenOutboxAlgorithm, expiresIn: cfgTokenOutboxExpires}; + let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; return jwt.sign(data, secret, options); } exports.fillJwtForRequest = fillJwtForRequest; @@ -938,10 +959,12 @@ exports.isLiveViewerSupport = function(licenseInfo){ return licenseInfo.connectionsView > 0 || licenseInfo.usersViewCount > 0; }; exports.canIncludeOutboxAuthorization = function (ctx, url) { - if (cfgTokenEnableRequestOutbox) { - if (!outboxUrlExclusionRegex) { + const tenTokenEnableRequestOutbox = ctx.getCfg('services.CoAuthoring.token.enable.request.outbox', cfgTokenEnableRequestOutbox); + const tenTokenOutboxUrlExclusionRegex = ctx.getCfg('services.CoAuthoring.token.outbox.urlExclusionRegex', cfgTokenOutboxUrlExclusionRegex); + if (tenTokenEnableRequestOutbox) { + if (!tenTokenOutboxUrlExclusionRegex) { return true; - } else if (!outboxUrlExclusionRegex.test(url)) { + } else if (!new RegExp(escapeStringRegexp(tenTokenOutboxUrlExclusionRegex)).test(url)) { return true; } else { ctx.logger.debug('canIncludeOutboxAuthorization excluded by token.outbox.urlExclusionRegex url=%s', url); @@ -949,16 +972,20 @@ exports.canIncludeOutboxAuthorization = function (ctx, url) { } return false; }; -exports.encryptPassword = co.wrap(function* (password) { - let params = {message: openpgp.message.fromText(password)}; - Object.assign(params, cfgPasswordEncrypt); +exports.encryptPassword = co.wrap(function* (ctx, password) { + const tenPasswordConfig = ctx.getCfg('openpgpjs.config', cfgPasswordConfig); + const tenPasswordEncrypt = ctx.getCfg('openpgpjs.encrypt', cfgPasswordEncrypt); + let params = {message: openpgp.message.fromText(password), config: tenPasswordConfig}; + Object.assign(params, tenPasswordEncrypt); const { data: encrypted } = yield openpgp.encrypt(params); return encrypted; }); -exports.decryptPassword = co.wrap(function* (password) { +exports.decryptPassword = co.wrap(function* (ctx, password) { + const tenPasswordConfig = ctx.getCfg('openpgpjs.config', cfgPasswordConfig); + const tenPasswordDecrypt = ctx.getCfg('openpgpjs.decrypt', cfgPasswordDecrypt); const message = yield openpgp.message.readArmored(password); - let params = {message: message}; - Object.assign(params, cfgPasswordDecrypt); + let params = {message: message, config: tenPasswordConfig}; + Object.assign(params, tenPasswordDecrypt); const { data: decrypted } = yield openpgp.decrypt(params); return decrypted; }); @@ -1011,8 +1038,9 @@ exports.convertLicenseInfoToServerParams = function(licenseInfo) { license.buildNumber = commonDefines.buildNumber; return license; }; -exports.checkBaseUrl = function(baseUrl) { - return cfgStorageExternalHost ? cfgStorageExternalHost : baseUrl; +exports.checkBaseUrl = function(ctx, baseUrl) { + const tenStorageExternalHost = ctx.getCfg('storage.externalHost', cfgStorageExternalHost); + return tenStorageExternalHost ? tenStorageExternalHost : baseUrl; }; exports.resolvePath = function(object, path, defaultValue) { return path.split('.').reduce((o, p) => o ? o[p] : defaultValue, object); diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 94f78472..84103bdd 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -708,16 +708,16 @@ function* sendServerRequest(ctx, uri, dataObject, opt_checkAndFixAuthorizationLe let auth; if (utils.canIncludeOutboxAuthorization(ctx, uri)) { let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Outbox); - let bodyToken = utils.fillJwtForRequest(dataObject, secret, true); - auth = utils.fillJwtForRequest(dataObject, secret, false); + let bodyToken = utils.fillJwtForRequest(ctx, dataObject, secret, true); + auth = utils.fillJwtForRequest(ctx, dataObject, secret, false); let authLen = auth.length; if (opt_checkAndFixAuthorizationLength && !opt_checkAndFixAuthorizationLength(auth, dataObject)) { - auth = utils.fillJwtForRequest(dataObject, secret, false); + auth = utils.fillJwtForRequest(ctx, dataObject, secret, false); ctx.logger.warn('authorization too large. Use body token instead. size reduced from %d to %d', authLen, auth.length); } dataObject.setToken(bodyToken); } - let postRes = yield utils.postRequestPromise(uri, JSON.stringify(dataObject), undefined, undefined, cfgCallbackRequestTimeout, auth); + let postRes = yield utils.postRequestPromise(ctx, uri, JSON.stringify(dataObject), undefined, undefined, cfgCallbackRequestTimeout, auth); ctx.logger.debug('postData response: data = %s', postRes.body); return postRes.body; } @@ -1428,7 +1428,7 @@ function encryptPasswordParams(ctx, data) { ctx.logger.warn('encryptPasswordParams password too long actual = %s; max = %s', dataWithPassword.password.length, constants.PASSWORD_MAX_LENGTH); dataWithPassword.password = null; } else { - dataWithPassword.password = yield utils.encryptPassword(dataWithPassword.password); + dataWithPassword.password = yield utils.encryptPassword(ctx, dataWithPassword.password); } } if (dataWithPassword && dataWithPassword.savepassword) { @@ -1437,7 +1437,7 @@ function encryptPasswordParams(ctx, data) { ctx.logger.warn('encryptPasswordParams password too long actual = %s; max = %s', dataWithPassword.savepassword.length, constants.PASSWORD_MAX_LENGTH); dataWithPassword.savepassword = null; } else { - dataWithPassword.savepassword = yield utils.encryptPassword(dataWithPassword.savepassword); + dataWithPassword.savepassword = yield utils.encryptPassword(ctx, dataWithPassword.savepassword); } } }); diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 1d959b9e..167419c1 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -239,8 +239,8 @@ var getOutputData = co.wrap(function* (ctx, cmd, outputData, key, optConn, optAd let decryptedPassword; let isCorrectPassword; if (password && encryptedUserPassword) { - decryptedPassword = yield utils.decryptPassword(password); - userPassword = yield utils.decryptPassword(encryptedUserPassword); + decryptedPassword = yield utils.decryptPassword(ctx, password); + userPassword = yield utils.decryptPassword(ctx, encryptedUserPassword); isCorrectPassword = decryptedPassword === userPassword; } if(password && !isCorrectPassword) { @@ -667,7 +667,7 @@ function* commandImgurls(ctx, conn, cmd, outputData) { for (let i = 0; i < urls.length; ++i) { if (utils.canIncludeOutboxAuthorization(ctx, urls[i])) { let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Outbox); - authorizations[i] = [utils.fillJwtForRequest({url: urls[i]}, secret, false)]; + authorizations[i] = [utils.fillJwtForRequest(ctx, {url: urls[i]}, secret, false)]; } } } else { @@ -1469,7 +1469,7 @@ exports.saveFile = function(req, res) { }; function getPrintFileUrl(ctx, docId, baseUrl, filename) { return co(function*() { - baseUrl = utils.checkBaseUrl(baseUrl); + baseUrl = utils.checkBaseUrl(ctx, baseUrl); let token = ''; if (cfgTokenEnableBrowser) { let payload = {document: {key: docId}}; @@ -1573,7 +1573,7 @@ exports.downloadFile = function(req, res) { } if (utils.canIncludeOutboxAuthorization(ctx, url)) { let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Outbox); - authorization = utils.fillJwtForRequest({url: url}, secret, false); + authorization = utils.fillJwtForRequest(ctx, {url: url}, secret, false); } } let urlParsed = urlModule.parse(url); diff --git a/DocService/sources/changes2forgotten.js b/DocService/sources/changes2forgotten.js index 266dba98..59ecd17e 100644 --- a/DocService/sources/changes2forgotten.js +++ b/DocService/sources/changes2forgotten.js @@ -55,7 +55,7 @@ var redisKeyShutdown = cfgRedisPrefix + constants.REDIS_KEY_SHUTDOWN; var WAIT_TIMEOUT = 30000; var LOOP_TIMEOUT = 1000; -var EXEC_TIMEOUT = WAIT_TIMEOUT + utils.CONVERTION_TIMEOUT; +var EXEC_TIMEOUT = WAIT_TIMEOUT + utils.getConvertionTimeout(undefined); let addSqlParam = sqlBase.baseConnector.addSqlParameter; function getDocumentsWithChanges(ctx) { diff --git a/DocService/sources/converterservice.js b/DocService/sources/converterservice.js index d68d3fa4..0909a4f0 100644 --- a/DocService/sources/converterservice.js +++ b/DocService/sources/converterservice.js @@ -67,8 +67,8 @@ function* getConvertStatus(ctx, docId, encryptedUserPassword, selectRes, opt_che if (password) { let isCorrectPassword; if (encryptedUserPassword) { - let decryptedPassword = yield utils.decryptPassword(password); - let userPassword = yield utils.decryptPassword(encryptedUserPassword); + let decryptedPassword = yield utils.decryptPassword(ctx, password); + let userPassword = yield utils.decryptPassword(ctx, encryptedUserPassword); isCorrectPassword = decryptedPassword === userPassword; } if (isCorrectPassword) { @@ -97,7 +97,7 @@ function* getConvertStatus(ctx, docId, encryptedUserPassword, selectRes, opt_che break; } var lastOpenDate = row.last_open_date; - if (new Date().getTime() - lastOpenDate.getTime() > utils.CONVERTION_TIMEOUT) { + if (new Date().getTime() - lastOpenDate.getTime() > utils.getConvertionTimeout(ctx)) { status.err = constants.CONVERT_TIMEOUT; } } else { @@ -172,7 +172,7 @@ function* convertByCmd(ctx, cmd, async, opt_fileTo, opt_taskExist, opt_priority, selectRes = yield taskResult.select(ctx, docId); status = yield* getConvertStatus(ctx, cmd.getDocId() ,cmd.getPassword(), selectRes, opt_checkPassword); waitTime += CONVERT_ASYNC_DELAY; - if (waitTime > utils.CONVERTION_TIMEOUT) { + if (waitTime > utils.getConvertionTimeout(ctx)) { status.err = constants.CONVERT_TIMEOUT; } } @@ -293,7 +293,7 @@ function convertRequest(req, res, isJson) { utils.fillResponse(req, res, new commonDefines.ConvertStatus(constants.CONVERT_PARAMS), isJson); return; } - let encryptedPassword = yield utils.encryptPassword(params.password); + let encryptedPassword = yield utils.encryptPassword(ctx, params.password); cmd.setPassword(encryptedPassword); } if (authRes.isDecoded) { diff --git a/DocService/sources/shutdown.js b/DocService/sources/shutdown.js index 251b221f..edd92320 100644 --- a/DocService/sources/shutdown.js +++ b/DocService/sources/shutdown.js @@ -45,7 +45,7 @@ var redisKeyShutdown = cfgRedisPrefix + constants.REDIS_KEY_SHUTDOWN; var WAIT_TIMEOUT = 30000; var LOOP_TIMEOUT = 1000; -var EXEC_TIMEOUT = WAIT_TIMEOUT + utils.CONVERTION_TIMEOUT; +var EXEC_TIMEOUT = WAIT_TIMEOUT + utils.getConvertionTimeout(undefined); exports.shutdown = function(ctx, editorData, status) { return co(function*() { diff --git a/DocService/sources/wopiClient.js b/DocService/sources/wopiClient.js index 0eeba4db..76a0c01f 100644 --- a/DocService/sources/wopiClient.js +++ b/DocService/sources/wopiClient.js @@ -538,7 +538,7 @@ function putFile(ctx, wopiParams, data, dataStream, dataSize, userLastChangeId, } ctx.logger.debug('wopi PutFile request uri=%s headers=%j', uri, headers); - postRes = yield utils.postRequestPromise(uri, data, dataStream, dataSize, cfgCallbackRequestTimeout, undefined, headers); + postRes = yield utils.postRequestPromise(ctx, uri, data, dataStream, dataSize, cfgCallbackRequestTimeout, undefined, headers); ctx.logger.debug('wopi PutFile response headers=%j', postRes.response.headers); ctx.logger.debug('wopi PutFile response body:%s', postRes.body); } else { @@ -569,7 +569,7 @@ function putRelativeFile(ctx, wopiSrc, access_token, data, dataStream, dataSize, fillStandardHeaders(headers, uri, access_token); ctx.logger.debug('wopi putRelativeFile request uri=%s headers=%j', uri, headers); - postRes = yield utils.postRequestPromise(uri, data, dataStream, dataSize, cfgCallbackRequestTimeout, undefined, headers); + postRes = yield utils.postRequestPromise(ctx, uri, data, dataStream, dataSize, cfgCallbackRequestTimeout, undefined, headers); ctx.logger.debug('wopi putRelativeFile response headers=%j', postRes.response.headers); ctx.logger.debug('wopi putRelativeFile response body:%s', postRes.body); } catch (err) { @@ -605,7 +605,7 @@ function renameFile(ctx, wopiParams, name) { fillStandardHeaders(headers, uri, userAuth.access_token); ctx.logger.debug('wopi RenameFile request uri=%s headers=%j', uri, headers); - let postRes = yield utils.postRequestPromise(uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); + let postRes = yield utils.postRequestPromise(ctx, uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); ctx.logger.debug('wopi RenameFile response headers=%j body=%s', postRes.response.headers, postRes.body); if (postRes.body) { res = JSON.parse(postRes.body); @@ -672,7 +672,7 @@ function lock(ctx, command, lockId, fileInfo, userAuth) { let headers = {"X-WOPI-Override": command, "X-WOPI-Lock": lockId}; fillStandardHeaders(headers, uri, access_token); ctx.logger.debug('wopi %s request uri=%s headers=%j', command, uri, headers); - let postRes = yield utils.postRequestPromise(uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); + let postRes = yield utils.postRequestPromise(ctx, uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); ctx.logger.debug('wopi %s response headers=%j', command, postRes.response.headers); } else { ctx.logger.info('wopi %s SupportsLocks = false', command); @@ -707,7 +707,7 @@ function unlock(ctx, wopiParams) { let headers = {"X-WOPI-Override": "UNLOCK", "X-WOPI-Lock": lockId}; fillStandardHeaders(headers, uri, access_token); ctx.logger.debug('wopi Unlock request uri=%s headers=%j', uri, headers); - let postRes = yield utils.postRequestPromise(uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); + let postRes = yield utils.postRequestPromise(ctx, uri, undefined, undefined, undefined, cfgCallbackRequestTimeout, undefined, headers); ctx.logger.debug('wopi Unlock response headers=%j', postRes.response.headers); } else { ctx.logger.info('wopi SupportsLocks = false'); diff --git a/FileConverter/sources/converter.js b/FileConverter/sources/converter.js index 2841cc8f..ff80a674 100644 --- a/FileConverter/sources/converter.js +++ b/FileConverter/sources/converter.js @@ -89,7 +89,7 @@ var exitCodesUpload = [constants.NO_ERROR, constants.CONVERT_CORRUPTED, constant constants.CONVERT_DRM, constants.CONVERT_DRM_UNSUPPORTED]; let inputLimitsXmlCache; -function TaskQueueDataConvert(task) { +function TaskQueueDataConvert(ctx, task) { var cmd = task.getCmd(); this.key = cmd.savekey ? cmd.savekey : cmd.id; this.fileFrom = null; @@ -109,13 +109,15 @@ function TaskQueueDataConvert(task) { this.fromChanges = task.getFromChanges(); //todo //todo - if (cfgFontDir) { - this.fontDir = path.resolve(cfgFontDir); + const tenFontDir = ctx.getCfg('FileConverter.converter.fontDir', cfgFontDir); + if (tenFontDir) { + this.fontDir = path.resolve(tenFontDir); } else { - this.fontDir = cfgFontDir; + this.fontDir = null; } //todo - this.themeDir = path.resolve(cfgPresentationThemesDir); + const tenPresentationThemesDir = ctx.getCfg('FileConverter.converter.presentationThemesDir', cfgPresentationThemesDir); + this.themeDir = path.resolve(tenPresentationThemesDir); this.mailMergeSend = cmd.mailmergesend; this.thumbnail = cmd.thumbnail; this.textParams = cmd.getTextParams(); @@ -128,7 +130,7 @@ function TaskQueueDataConvert(task) { this.timestamp = new Date(); } TaskQueueDataConvert.prototype = { - serialize: function(fsPath) { + serialize: function(ctx, fsPath) { let xml = '\ufeff'; xml += '