diff --git a/src/apps.js b/src/apps.js index 5d999060e..a75ec81a5 100644 --- a/src/apps.js +++ b/src/apps.js @@ -14,7 +14,6 @@ exports = module.exports = { getAll: getAll, getAllByUser: getAllByUser, install: install, - configure: configure, uninstall: uninstall, setAccessRestriction: setAccessRestriction, @@ -1178,148 +1177,6 @@ function setDataDir(appId, dataDir, auditSource, callback) { }); } -function configure(appId, data, user, auditSource, callback) { - assert.strictEqual(typeof appId, 'string'); - assert(data && typeof data === 'object'); - assert(user && typeof user === 'object'); - assert.strictEqual(typeof auditSource, 'object'); - assert.strictEqual(typeof callback, 'function'); - - get(appId, function (error, app) { - if (error) return callback(error); - if (app.taskId) return callback(new AppsError(AppsError.BAD_STATE, `Not allowed in this app state : ${app.installationState} / ${app.runState}`)); - - let domain, location, portBindings, values = { installationState: exports.ISTATE_PENDING_CONFIGURE }; - - if ('location' in data && 'domain' in data) { - location = values.location = data.location.toLowerCase(); - domain = values.domain = data.domain.toLowerCase(); - } else { - location = app.location; - domain = app.domain; - } - - if ('accessRestriction' in data) { - values.accessRestriction = data.accessRestriction; - error = validateAccessRestriction(values.accessRestriction); - if (error) return callback(error); - } - - if ('portBindings' in data) { - error = validatePortBindings(data.portBindings, app.manifest); - if (error) return callback(error); - values.portBindings = translatePortBindings(data.portBindings, app.manifest); - portBindings = data.portBindings; - } else { - portBindings = app.portBindings; - } - - if ('memoryLimit' in data) { - values.memoryLimit = data.memoryLimit; - error = validateMemoryLimit(app.manifest, values.memoryLimit); - if (error) return callback(error); - } - - if ('debugMode' in data) { - values.debugMode = data.debugMode; - error = validateDebugMode(values.debugMode); - if (error) return callback(error); - } - - if ('robotsTxt' in data) { - values.robotsTxt = data.robotsTxt || null; - error = validateRobotsTxt(values.robotsTxt); - if (error) return callback(error); - } - - if ('mailboxName' in data) { - if (data.mailboxName) { - error = mail.validateName(data.mailboxName); - if (error) return callback(new AppsError(AppsError.BAD_FIELD, error.message, { field: 'mailboxName' })); - values.mailboxName = data.mailboxName; - } else { - values.mailboxName = mailboxNameForLocation(location, app.manifest); - } - } else { // keep existing name or follow the new location - values.mailboxName = app.mailboxName.endsWith('.app') ? mailboxNameForLocation(location, app.manifest) : app.mailboxName; - } - - if ('alternateDomains' in data) { - // TODO validate all subdomains [{ domain: '', subdomain: ''}] - values.alternateDomains = data.alternateDomains; - } - - if ('env' in data) { - values.env = data.env; - error = validateEnv(data.env); - if (error) return callback(error); - } - - if ('dataDir' in data && data.dataDir !== app.dataDir) { - error = validateDataDir(data.dataDir); - if (error) return callback(error); - values.dataDir = data.dataDir; - } - - if ('label' in data) { - error = validateLabel(data.label); - if (error) return callback(error); - values.label = data.label; - } - - if ('tags' in data) { - error = validateTags(data.tags); - if (error) return callback(error); - values.tags = data.tags; - } - - if ('icon' in data) { - if (data.icon) { - if (!validator.isBase64(data.icon)) return callback(new AppsError(AppsError.BAD_FIELD, 'icon is not base64', { field: 'icon' })); - - if (!safe.fs.writeFileSync(path.join(paths.APP_ICONS_DIR, appId + '.user.png'), Buffer.from(data.icon, 'base64'))) { - return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving icon:' + safe.error.message)); - } - } else { - safe.fs.unlinkSync(path.join(paths.APP_ICONS_DIR, appId + '.user.png')); - } - } - - domains.get(domain, function (error, domainObject) { - if (error && error.reason === DomainsError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such domain')); - if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Could not get domain info:' + error.message)); - - error = domains.validateHostname(location, domainObject); - if (error) return callback(new AppsError(AppsError.BAD_FIELD, 'Bad location: ' + error.message, { field: 'location' })); - - // save cert to boxdata/certs. TODO: move this to apptask when we have a real task queue - if ('cert' in data && 'key' in data) { - if (data.cert && data.key) { - error = reverseProxy.validateCertificate(location, domainObject, { cert: data.cert, key: data.key }); - if (error) return callback(new AppsError(AppsError.BAD_FIELD, error.message, { field: 'cert' })); - } - - error = reverseProxy.setAppCertificateSync(location, domainObject, { cert: data.cert, key: data.key }); - if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error setting cert: ' + error.message)); - } - - if ('enableBackup' in data) values.enableBackup = data.enableBackup; - if ('enableAutomaticUpdate' in data) values.enableAutomaticUpdate = data.enableAutomaticUpdate; - - debug(`configure: id:${appId}`); - - scheduleTask(appId, { oldConfig: getAppConfig(app) }, values, function (error, result) { - if (error && error.reason === AppsError.ALREADY_EXISTS) error = getDuplicateErrorDetails(error.message, location, domainObject, portBindings, data.alternateDomains); - if (error) return callback(error); - - eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, config: values, taskId: result.taskId }); - - callback(null, { taskId: result.taskId }); - }); - }); - }); -} - function update(appId, data, auditSource, callback) { assert.strictEqual(typeof appId, 'string'); assert(data && typeof data === 'object'); diff --git a/src/routes/apps.js b/src/routes/apps.js index 02bd6005b..14da00f9e 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -5,7 +5,6 @@ exports = module.exports = { getApps: getApps, getAppIcon: getAppIcon, installApp: installApp, - configureApp: configureApp, uninstallApp: uninstallApp, restoreApp: restoreApp, backupApp: backupApp, @@ -358,61 +357,6 @@ function setDataDir(req, res, next) { }); } -function configureApp(req, res, next) { - assert.strictEqual(typeof req.body, 'object'); - assert.strictEqual(typeof req.params.id, 'string'); - - var data = req.body; - - if ('location' in data && typeof data.location !== 'string') return next(new HttpError(400, 'location must be string')); - if ('domain' in data && typeof data.domain !== 'string') return next(new HttpError(400, 'domain must be string')); - // domain, location must both be provided since they are unique together - if ('location' in data && !('domain' in data)) return next(new HttpError(400, 'domain must be provided')); - if (!('location' in data) && 'domain' in data) return next(new HttpError(400, 'location must be provided')); - - if ('portBindings' in data && typeof data.portBindings !== 'object') return next(new HttpError(400, 'portBindings must be an object')); - if ('accessRestriction' in data && typeof data.accessRestriction !== 'object') return next(new HttpError(400, 'accessRestriction must be an object')); - - // falsy values in cert and key unset the cert - if (data.key && typeof data.cert !== 'string') return next(new HttpError(400, 'cert must be a string')); - if (data.cert && typeof data.key !== 'string') return next(new HttpError(400, 'key must be a string')); - if (data.cert && !data.key) return next(new HttpError(400, 'key must be provided')); - if (!data.cert && data.key) return next(new HttpError(400, 'cert must be provided')); - - if ('memoryLimit' in data && typeof data.memoryLimit !== 'number') return next(new HttpError(400, 'memoryLimit is not a number')); - - if ('enableBackup' in data && typeof data.enableBackup !== 'boolean') return next(new HttpError(400, 'enableBackup must be a boolean')); - if ('enableAutomaticUpdate' in data && typeof data.enableAutomaticUpdate !== 'boolean') return next(new HttpError(400, 'enableAutomaticUpdate must be a boolean')); - - if (('debugMode' in data) && typeof data.debugMode !== 'object') return next(new HttpError(400, 'debugMode must be an object')); - - if (data.robotsTxt && typeof data.robotsTxt !== 'string') return next(new HttpError(400, 'robotsTxt must be a string')); - - if ('mailboxName' in data && typeof data.mailboxName !== 'string') return next(new HttpError(400, 'mailboxName must be a string')); - - if ('alternateDomains' in data) { - if (!Array.isArray(data.alternateDomains)) return next(new HttpError(400, 'alternateDomains must be an array')); - if (data.alternateDomains.some(function (d) { return (typeof d.domain !== 'string' || typeof d.subdomain !== 'string'); })) return next(new HttpError(400, 'alternateDomains array must contain objects with domain and subdomain strings')); - } - - if ('env' in data) { - if (!data.env || typeof data.env !== 'object') return next(new HttpError(400, 'env must be an object')); - if (Object.keys(data.env).some(function (key) { return typeof data.env[key] !== 'string'; })) return next(new HttpError(400, 'env must contain values as strings')); - } - - if ('label' in data && typeof data.label !== 'string') return next(new HttpError(400, 'label must be a string')); - if ('dataDir' in data && typeof data.dataDir !== 'string') return next(new HttpError(400, 'dataDir must be a string')); - if ('icon' in data && typeof data.icon !== 'string') return next(new HttpError(400, 'icon is not a string')); - - debug('Configuring app id:%s data:%j', req.params.id, data); - - apps.configure(req.params.id, data, req.user, auditSource.fromRequest(req), function (error, result) { - if (error) return next(toHttpError(error)); - - next(new HttpSuccess(202, { taskId: result.taskId })); - }); -} - function restoreApp(req, res, next) { assert.strictEqual(typeof req.body, 'object'); assert.strictEqual(typeof req.params.id, 'string'); diff --git a/src/server.js b/src/server.js index 825da57e5..a922a856d 100644 --- a/src/server.js +++ b/src/server.js @@ -227,7 +227,6 @@ function initializeExpressSync() { router.post('/api/v1/apps/install', appsManageScope, routes.apps.installApp); router.post('/api/v1/apps/:id/uninstall', appsManageScope, routes.apps.uninstallApp); - router.post('/api/v1/apps/:id/configure', appsManageScope, routes.apps.configureApp); router.post('/api/v1/apps/:id/configure/access_restriction', appsManageScope, routes.apps.setAccessRestriction); router.post('/api/v1/apps/:id/configure/label', appsManageScope, routes.apps.setLabel); router.post('/api/v1/apps/:id/configure/tags', appsManageScope, routes.apps.setTags);