diff --git a/controllers/api/applications.js b/controllers/api/applications.js index c118d6ac..4a377a3b 100755 --- a/controllers/api/applications.js +++ b/controllers/api/applications.js @@ -10,6 +10,9 @@ const Op = Sequelize.Op; const api_check_perm_controller = require('./check_permissions'); +const generate_app_certificates = require('../../lib/app_certificates.js').generate_app_certificates; +const delete_app_certificates = require('../../lib/app_certificates.js').delete_app_certificates; + // MW to Autoload info if path include application_id exports.load_application = function (req, res, next, application_id) { debug('--> load_application'); @@ -165,6 +168,8 @@ exports.create = function (req, res) { application.scope = req.body.application.scope ? req.body.application.scope : null; + const promises = []; + if (req.body.application.token_types || (application.scope && application.scope.includes('openid'))) { application.jwt_secret = req.body.application.token_types.includes('jwt') ? crypto.randomBytes(16).toString('hex').slice(0, 16) @@ -197,7 +202,14 @@ exports.create = function (req, res) { }); }); - return Promise.all([create_application, create_assignment]) + promises.push(create_application); + promises.push(create_assignment); + + if (application.scope && application.scope.includes('openid')) { + promises.push(generate_app_certificates(application)); + } + + return Promise.all(promises) .then(function (values) { res.status(201).json({ application: values[0].dataValues }); }) @@ -278,19 +290,40 @@ exports.update = function (req, res) { req.application.response_type = oauth_type.response_type; } - return req.application.save(); - }) - .then(function (application) { - const difference = diff_object(application_previous_values, application.dataValues); - const response = - Object.keys(difference).length > 0 - ? { values_updated: difference } - : { - message: "Request don't change the application parameters", - code: 200, - title: 'OK' - }; - res.status(200).json(response); + const diff_application = function (application) { + return new Promise((resolve, reject) => { + const difference = diff_object(application_previous_values, application.dataValues); + resolve( + Object.keys(difference).length > 0 + ? { values_updated: difference } + : { + message: "Request don't change the application parameters", + code: 200, + title: 'OK' + } + ); + }); + } + + req.application.save(); + + const promises = []; + + promises.push(diff_application(req.application)) + + if (req.application.scope.includes("openid")) { + promises.push(generate_app_certificates(req.application)); + } else { + promises.push(delete_app_certificates(req.application)); + } + + return Promise.all(promises) + .then(function (values) { + res.status(200).json(values[0]); + }) + .catch(function (error) { + return Promise.reject(error); + }); }) .catch(function (error) { debug('Error: ' + error); @@ -311,6 +344,9 @@ exports.update = function (req, res) { exports.delete = function (req, res) { debug('--> delete'); + // Delete certificates if exists + delete_app_certificates(req.application); + req.application .destroy() .then(function () { diff --git a/controllers/web/applications.js b/controllers/web/applications.js index cb398a00..c45990a4 100755 --- a/controllers/web/applications.js +++ b/controllers/web/applications.js @@ -1,7 +1,6 @@ const models = require('../../models/models.js'); const fs = require('fs'); const _ = require('lodash'); -const exec = require('child_process').exec; const config_service = require('../../lib/configService.js'); const config = config_service.get_config(); @@ -13,6 +12,9 @@ const gravatar = require('gravatar'); const image = require('../../lib/image.js'); const crypto = require('crypto'); +const generate_app_certificates = require('../../lib/app_certificates.js').generate_app_certificates; +const delete_app_certificates = require('../../lib/app_certificates.js').delete_app_certificates; + // Autoload info if path include application_id exports.load_application = function (req, res, next, application_id) { debug('--> load_application'); @@ -907,69 +909,3 @@ function send_response(req, res, response, url) { res.redirect(url); } } - -// Function to generate Application certificates -function generate_app_certificates(application) { - debug('--> generate_app_certificates'); - - if (!fs.existsSync('./certs/applications')) { - fs.mkdirSync('./certs/applications'); - } - - if (fs.existsSync('./certs/applications/' + application.id + '-oidc-key.pem')) { - return Promise.resolve(); - } - - return new Promise((resolve, reject) => { - const key_name = 'certs/applications/' + application.id + '-oidc-key.pem'; - const csr_name = 'certs/applications/' + application.id + '-oidc-csr.pem'; - const cert_name = 'certs/applications/' + application.id + '-oidc-cert.pem'; - - const key = 'openssl genrsa -out ' + key_name + ' 2048'; - const csr = - 'openssl req -new -sha256 -key ' + - key_name + - ' -out ' + - csr_name + - ' -subj "/C=IK/ST=World/L=World/' + - 'O=' + - application.name + - '/OU=' + - application.name + - '/CN=' + - config.host.split(':')[0] + - '"'; - - const cert = 'openssl x509 -days 365 -req -in ' + csr_name + ' -signkey ' + key_name + ' -out ' + cert_name; - - const create_certificates = key + ' && ' + csr + ' && ' + cert; - exec(create_certificates, function (error) { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); -} - -// Delete certificates -function delete_app_certificates(application) { - try { - if (fs.existsSync('./certs/applications')) { - if (fs.existsSync('./certs/applications/' + application.id + '-oidc-key.pem')) { - fs.unlinkSync('./certs/applications/' + application.id + '-oidc-key.pem'); - fs.unlinkSync('./certs/applications/' + application.id + '-oidc-cert.pem'); - fs.unlinkSync('./certs/applications/' + application.id + '-oidc-csr.pem'); - } - if (fs.existsSync('./certs/applications/' + application.id + '-key.pem')) { - fs.unlinkSync('./certs/applications/' + application.id + '-key.pem'); - fs.unlinkSync('./certs/applications/' + application.id + '-cert.pem'); - fs.unlinkSync('./certs/applications/' + application.id + '-csr.pem'); - } - } - } catch (err) { - console.error(err); - - } -} diff --git a/lib/app_certificates.js b/lib/app_certificates.js new file mode 100755 index 00000000..4661ffba --- /dev/null +++ b/lib/app_certificates.js @@ -0,0 +1,74 @@ +const fs = require('fs'); +const exec = require('child_process').exec; + +const config_service = require('./configService.js'); +const config = config_service.get_config(); + +const debug = require('debug')('idm:web-application_controller'); + +// Function to generate Application certificates +exports.generate_app_certificates = function (application) { + debug('--> generate_app_certificates'); + + if (!fs.existsSync('./certs/applications')) { + fs.mkdirSync('./certs/applications'); + } + + if (fs.existsSync('./certs/applications/' + application.id + '-oidc-key.pem')) { + return Promise.resolve(); + } + + return new Promise((resolve, reject) => { + const key_name = 'certs/applications/' + application.id + '-oidc-key.pem'; + const csr_name = 'certs/applications/' + application.id + '-oidc-csr.pem'; + const cert_name = 'certs/applications/' + application.id + '-oidc-cert.pem'; + + const key = 'openssl genrsa -out ' + key_name + ' 2048'; + const csr = + 'openssl req -new -sha256 -key ' + + key_name + + ' -out ' + + csr_name + + ' -subj "/C=IK/ST=World/L=World/' + + 'O=' + + application.name + + '/OU=' + + application.name + + '/CN=' + + config.host.split(':')[0] + + '"'; + + const cert = 'openssl x509 -days 365 -req -in ' + csr_name + ' -signkey ' + key_name + ' -out ' + cert_name; + + const create_certificates = key + ' && ' + csr + ' && ' + cert; + exec(create_certificates, function (error) { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); +} + +// Delete certificates +exports.delete_app_certificates = function (application) { + debug('--> delete_app_certificates'); + + try { + if (fs.existsSync('./certs/applications')) { + if (fs.existsSync('./certs/applications/' + application.id + '-oidc-key.pem')) { + fs.unlinkSync('./certs/applications/' + application.id + '-oidc-key.pem'); + fs.unlinkSync('./certs/applications/' + application.id + '-oidc-cert.pem'); + fs.unlinkSync('./certs/applications/' + application.id + '-oidc-csr.pem'); + } + if (fs.existsSync('./certs/applications/' + application.id + '-key.pem')) { + fs.unlinkSync('./certs/applications/' + application.id + '-key.pem'); + fs.unlinkSync('./certs/applications/' + application.id + '-cert.pem'); + fs.unlinkSync('./certs/applications/' + application.id + '-csr.pem'); + } + } + } catch (err) { + console.error(err); + } +} diff --git a/models/oauth2/oauth_client.js b/models/oauth2/oauth_client.js index c0fa4442..e111125f 100755 --- a/models/oauth2/oauth_client.js +++ b/models/oauth2/oauth_client.js @@ -98,7 +98,9 @@ module.exports = function (sequelize, DataTypes) { }, set(val) { if (val && val.length > 0) { - val.push('bearer'); + if (val.indexOf('bearer') == -1) { + val.push('bearer'); + } } else { val = ['bearer']; }