diff --git a/src/auditsource.js b/src/auditsource.js index 18c297cdd..f8bf3b597 100644 --- a/src/auditsource.js +++ b/src/auditsource.js @@ -3,7 +3,6 @@ exports = module.exports = { CRON: { userId: null, username: 'cron' }, HEALTH_MONITOR: { userId: null, username: 'healthmonitor' }, - SYSADMIN: { userId: null, username: 'sysadmin' }, APP_TASK: { userId: null, username: 'apptask' }, EXTERNAL_LDAP_TASK: { userId: null, username: 'externalldap' }, diff --git a/src/constants.js b/src/constants.js index 4ba6ca063..b46be2d40 100644 --- a/src/constants.js +++ b/src/constants.js @@ -26,7 +26,7 @@ exports = module.exports = { PORT: CLOUDRON ? 3000 : 5454, INTERNAL_SMTP_PORT: 2525, // this value comes from the mail container - SYSADMIN_PORT: 3001, + SYSADMIN_PORT: 3001, // unused LDAP_PORT: 3002, DOCKER_PROXY_PORT: 3003, diff --git a/src/routes/index.js b/src/routes/index.js index b9600837b..0aaa8fc73 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -20,7 +20,6 @@ exports = module.exports = { services: require('./services.js'), settings: require('./settings.js'), support: require('./support.js'), - sysadmin: require('./sysadmin.js'), tasks: require('./tasks.js'), users: require('./users.js') }; diff --git a/src/routes/sysadmin.js b/src/routes/sysadmin.js deleted file mode 100644 index a44f308d0..000000000 --- a/src/routes/sysadmin.js +++ /dev/null @@ -1,71 +0,0 @@ -'use strict'; - -exports = module.exports = { - backup: backup, - update: update, - retire: retire, - - importAppDatabase: importAppDatabase -}; - -var apps = require('../apps.js'), - AppsError = apps.AppsError, - addons = require('../addons.js'), - auditSource = require('../auditsource.js'), - backups = require('../backups.js'), - BackupsError = require('../backups.js').BackupsError, - cloudron = require('../cloudron.js'), - debug = require('debug')('box:routes/sysadmin'), - HttpError = require('connect-lastmile').HttpError, - HttpSuccess = require('connect-lastmile').HttpSuccess, - updater = require('../updater.js'), - UpdaterError = require('../updater.js').UpdaterError; - -function backup(req, res, next) { - debug('triggering backup'); - - // note that cloudron.backup only waits for backup initiation and not for backup to complete - // backup progress can be checked up ny polling the progress api call - backups.startBackupTask(auditSource.SYSADMIN, function (error, taskId) { - if (error && error.reason === BackupsError.BAD_STATE) return next(new HttpError(409, error.message)); - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(202, { taskId })); - }); -} - -function update(req, res, next) { - debug('triggering update'); - - // this only initiates the update, progress can be checked via the progress route - updater.updateToLatest({ skipBackup: false }, auditSource.SYSADMIN, function (error, taskId) { - if (error && error.reason === UpdaterError.ALREADY_UPTODATE) return next(new HttpError(422, error.message)); - if (error && error.reason === UpdaterError.BAD_STATE) return next(new HttpError(409, error.message)); - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(202, { taskId })); - }); -} - -function retire(req, res, next) { - debug('triggering retire'); - - cloudron.retire('migrate', { }, function (error) { - if (error) debug('Retire failed.', error); - }); - - next(new HttpSuccess(202, {})); -} - -function importAppDatabase(req, res, next) { - apps.get(req.params.id, function (error, app) { - if (error && error.reason === AppsError.NOT_FOUND) return next(new HttpError(404, 'No such app')); - if (error) return next(new HttpError(500, error)); - - addons.importAppDatabase(app, req.query.addon || '', function (error) { - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(202, {})); - }); - }); -} diff --git a/src/routes/test/sysadmin-test.js b/src/routes/test/sysadmin-test.js deleted file mode 100644 index c3ed8d2f7..000000000 --- a/src/routes/test/sysadmin-test.js +++ /dev/null @@ -1,88 +0,0 @@ -/* global it:false */ -/* global describe:false */ -/* global before:false */ -/* global after:false */ - -'use strict'; - -var async = require('async'), - constants = require('../../constants.js'), - database = require('../../database.js'), - domains = require('../../domains.js'), - eventlog = require('../../eventlog.js'), - expect = require('expect.js'), - server = require('../../server.js'), - settings = require('../../settings.js'), - settingsdb = require('../../settingsdb.js'), - superagent = require('superagent'); - -const SERVER_URL = 'http://localhost:' + constants.PORT; - -const USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com'; - -const DOMAIN_0 = { - domain: 'example-sysadmin-test.com', - zoneName: 'example-sysadmin-test.com', - config: {}, - provider: 'noop', - fallbackCertificate: null, - tlsConfig: { provider: 'fallback' } -}; - -let AUDIT_SOURCE = { ip: '1.2.3.4' }; - -function setup(done) { - async.series([ - server.start, - database._clear, - domains.add.bind(null, DOMAIN_0.domain, DOMAIN_0, AUDIT_SOURCE), - - function createAdmin(callback) { - superagent.post(SERVER_URL + '/api/v1/cloudron/activate') - .query({ setupToken: 'somesetuptoken' }) - .send({ username: USERNAME, password: PASSWORD, email: EMAIL }) - .end(function (error, result) { - expect(result).to.be.ok(); - expect(result.statusCode).to.eql(201); - callback(); - }); - }, - - function createSettings(callback) { - settingsdb.set(settings.BACKUP_CONFIG_KEY, JSON.stringify({ provider: 'filesystem', backupFolder: '/tmp/backups', prefix: 'boxid', format: 'tgz'}), callback); - } - ], done); -} - -function cleanup(done) { - database._clear(function (error) { - expect(!error).to.be.ok(); - server.stop(done); - }); -} - -describe('Internal API', function () { - before(setup); - after(cleanup); - - describe('backup', function () { - it('succeeds', function (done) { - superagent.post(`http://127.0.0.1:${constants.SYSADMIN_PORT}/api/v1/backup`) - .end(function (error, result) { - expect(result.statusCode).to.equal(202); - - function checkBackupStartEvent() { - eventlog.getAllPaged([ eventlog.ACTION_BACKUP_START ], '', 1, 100, function (error, result) { - expect(error).to.equal(null); - - if (result.length === 0) return setTimeout(checkBackupStartEvent, 1000); - - done(); - }); - } - - checkBackupStartEvent(); - }); - }); - }); -}); diff --git a/src/server.js b/src/server.js index a922a856d..d753f7fa8 100644 --- a/src/server.js +++ b/src/server.js @@ -23,7 +23,6 @@ var accesscontrol = require('./accesscontrol.js'), ws = require('ws'); var gHttpServer = null; -var gSysadminHttpServer = null; function initializeExpressSync() { var app = express(); @@ -340,38 +339,6 @@ function initializeExpressSync() { return httpServer; } -// provides local webhooks for sysadmins -function initializeSysadminExpressSync() { - var app = express(); - var httpServer = http.createServer(app); - - var QUERY_LIMIT = '1mb'; // max size for json and urlencoded queries - var REQUEST_TIMEOUT = 10000; // timeout for all requests - - var json = middleware.json({ strict: true, limit: QUERY_LIMIT }), // application/json - urlencoded = middleware.urlencoded({ extended: false, limit: QUERY_LIMIT }); // application/x-www-form-urlencoded - - if (process.env.BOX_ENV !== 'test') app.use(middleware.morgan('Box Sysadmin :method :url :status :response-time ms - :res[content-length]', { immediate: false })); - - var router = new express.Router(); - router.del = router.delete; // amend router.del for readability further on - - app - .use(middleware.timeout(REQUEST_TIMEOUT)) - .use(json) - .use(urlencoded) - .use(router) - .use(middleware.lastMile()); - - // Sysadmin routes - router.post('/api/v1/backup', routes.sysadmin.backup); - router.post('/api/v1/update', routes.sysadmin.update); - router.post('/api/v1/retire', routes.sysadmin.retire); - router.post('/api/v1/apps/:id/import', routes.sysadmin.importAppDatabase); - - return httpServer; -} - function start(callback) { assert.strictEqual(typeof callback, 'function'); assert.strictEqual(gHttpServer, null, 'Server is already up and running.'); @@ -379,7 +346,6 @@ function start(callback) { routes.oauth2.initialize(); // init's the oauth server gHttpServer = initializeExpressSync(); - gSysadminHttpServer = initializeSysadminExpressSync(); async.series([ routes.accesscontrol.initialize, // hooks up authentication strategies into passport @@ -387,7 +353,6 @@ function start(callback) { settings.initCache, // pre-load very often used settings cloudron.initialize, gHttpServer.listen.bind(gHttpServer, constants.PORT, '127.0.0.1'), - gSysadminHttpServer.listen.bind(gSysadminHttpServer, constants.SYSADMIN_PORT, '127.0.0.1'), eventlog.add.bind(null, eventlog.ACTION_START, { userId: null, username: 'boot' }, { version: constants.VERSION }) ], callback); } @@ -402,14 +367,12 @@ function stop(callback) { database.uninitialize, routes.accesscontrol.uninitialize, gHttpServer.close.bind(gHttpServer), - gSysadminHttpServer.close.bind(gSysadminHttpServer) ], function (error) { if (error) return callback(error); routes.oauth2.uninitialize(); gHttpServer = null; - gSysadminHttpServer = null; callback(null); });