diff --git a/CHANGES b/CHANGES index bbf2d2acf..16af35a5e 100644 --- a/CHANGES +++ b/CHANGES @@ -1860,4 +1860,5 @@ * Add type filter to mail eventlog * mail: Fix listing of mailboxes and aliases in the UI * branding: fix login page title +* Only a Cloudron owner can install/update/exec apps with the docker addon diff --git a/src/apps.js b/src/apps.js index 2efcb1ef3..070910016 100644 --- a/src/apps.js +++ b/src/apps.js @@ -1220,14 +1220,14 @@ function update(app, data, auditSource, callback) { assert.strictEqual(typeof callback, 'function'); const skipBackup = !!data.skipBackup, - manifest = data.manifest, - appId = app.id; + appId = app.id, + manifest = data.manifest; + + if (app.runState === exports.RSTATE_STOPPED) return callback(new BoxError(BoxError.BAD_STATE, 'Stopped apps cannot be updated')); let error = checkAppState(app, exports.ISTATE_PENDING_UPDATE); if (error) return callback(error); - if (app.runState === exports.RSTATE_STOPPED) return callback(new BoxError(BoxError.BAD_STATE, 'Stopped apps cannot be updated')); - error = manifestFormat.parse(manifest); if (error) return callback(new BoxError(BoxError.BAD_FIELD, 'Manifest error:' + error.message)); diff --git a/src/routes/apps.js b/src/routes/apps.js index 5223c3e0d..c678e7df4 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -641,7 +641,9 @@ function exec(req, res, next) { var rows = req.query.rows ? parseInt(req.query.rows, 10) : null; if (isNaN(rows)) return next(new HttpError(400, 'rows must be a number')); - var tty = req.query.tty === 'true' ? true : false; + var tty = req.query.tty === 'true'; + + if (safe.query(req.resource, 'manifest.addons.docker') && req.user.role !== users.ROLE_OWNER) return next(new HttpError(403, 'Only owner can exec app with docker addon')); apps.exec(req.resource, { cmd: cmd, rows: rows, columns: columns, tty: tty }, function (error, duplexStream) { if (error) return next(BoxError.toHttpError(error));