diff --git a/src/apps.js b/src/apps.js index 932721e32..b995521cf 100644 --- a/src/apps.js +++ b/src/apps.js @@ -119,6 +119,7 @@ AppsError.PORT_CONFLICT = 'Port Conflict'; AppsError.BILLING_REQUIRED = 'Billing Required'; AppsError.ACCESS_DENIED = 'Access denied'; AppsError.USER_REQUIRED = 'User required'; +AppsError.BAD_CERTIFICATE = 'Invalid certificate'; // Hostname validation comes from RFC 1123 (section 2.1) // Domain name validation comes from RFC 2181 (Name syntax) @@ -196,6 +197,18 @@ function validateAccessRestriction(accessRestriction) { return null; } +function validateCertificate(cert, key) { + assert(cert === null || typeof cert === 'string'); + assert(key === null || typeof key === 'string'); + + if (cert === null && key === null) return null; + if (cert === null && !key) return new Error('missing key'); + if (!cert && key === null) return new Error('missing cert'); + + // TODO more actual cert validation + return null; +} + function getDuplicateErrorDetails(location, portBindings, error) { assert.strictEqual(typeof location, 'string'); assert.strictEqual(typeof portBindings, 'object'); @@ -348,12 +361,14 @@ function install(appId, appStoreId, manifest, location, portBindings, accessRest }); } -function configure(appId, location, portBindings, accessRestriction, oauthProxy, callback) { +function configure(appId, location, portBindings, accessRestriction, oauthProxy, cert, key, callback) { assert.strictEqual(typeof appId, 'string'); assert.strictEqual(typeof location, 'string'); assert.strictEqual(typeof portBindings, 'object'); assert.strictEqual(typeof accessRestriction, 'object'); assert.strictEqual(typeof oauthProxy, 'boolean'); + assert(cert === null || typeof cert === 'string'); + assert(key === null || typeof key === 'string'); assert.strictEqual(typeof callback, 'function'); var error = validateHostname(location, config.fqdn()); @@ -362,6 +377,9 @@ function configure(appId, location, portBindings, accessRestriction, oauthProxy, error = validateAccessRestriction(accessRestriction); if (error) return callback(new AppsError(AppsError.BAD_FIELD, error.message)); + error = validateCertificate(cert, key); + if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message)); + appdb.get(appId, function (error, app) { if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app')); if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); diff --git a/src/routes/apps.js b/src/routes/apps.js index a58d5ffc2..39c7a1997 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -159,13 +159,14 @@ function configureApp(req, res, next) { debug('Configuring app id:%s location:%s bindings:%j accessRestriction:%j oauthProxy:%s', req.params.id, data.location, data.portBindings, data.accessRestriction, data.oauthProxy); - apps.configure(req.params.id, data.location, data.portBindings || null, data.accessRestriction, data.oauthProxy, function (error) { + apps.configure(req.params.id, data.location, data.portBindings || null, data.accessRestriction, data.oauthProxy, data.cert || null, data.key || null, function (error) { if (error && error.reason === AppsError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); if (error && error.reason === AppsError.PORT_RESERVED) return next(new HttpError(409, 'Port ' + error.message + ' is reserved.')); if (error && error.reason === AppsError.PORT_CONFLICT) return next(new HttpError(409, 'Port ' + error.message + ' is already in use.')); if (error && error.reason === AppsError.NOT_FOUND) return next(new HttpError(404, 'No such app')); if (error && error.reason === AppsError.BAD_STATE) return next(new HttpError(409, error.message)); if (error && error.reason === AppsError.BAD_FIELD) return next(new HttpError(400, error.message)); + if (error && error.reason === AppsError.BAD_CERTIFICATE) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(202, { }));