Merge pull request #3841 from halfdan/3619-configuration-api

Implements new Configuration API
This commit is contained in:
Sebastian Gierlinger 2014-09-01 15:15:05 +02:00
commit 57b5f4da00
6 changed files with 173 additions and 0 deletions

View File

@ -0,0 +1,78 @@
// # Configuration API
// RESTful API for browsing the configuration
var _ = require('lodash'),
canThis = require('../permissions').canThis,
config = require('../config'),
errors = require('../errors'),
parsePackageJson = require('../require-tree').parsePackageJson,
Promise = require('bluebird'),
configuration;
function getValidKeys() {
var validKeys = {
'fileStorage': config.fileStorage === false ? false : true,
'apps': config.apps || false,
'version': false,
'environment': process.env.NODE_ENV,
'database': config.database.client,
'mail': _.isObject(config.mail) ? config.mail.transport : '',
'blogUrl': config.url
};
return parsePackageJson('package.json').then(function (json) {
validKeys.version = json.version;
return validKeys;
});
}
/**
* ## Configuration API Methods
*
* **See:** [API Methods](index.js.html#api%20methods)
*/
configuration = {
/**
* ### Browse
* Fetch all configuration keys
* @returns {Promise(Configurations)}
*/
browse: function browse(options) {
return canThis(options.context).browse.configuration().then(function () {
return getValidKeys().then(function (result) {
return { 'configuration': _.map(result, function (value, key) {
return {
key: key,
value: value
};
})};
});
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse the configuration.'));
});
},
/**
* ### Read
*
*/
read: function read(options) {
return canThis(options.context).read.configuration().then(function () {
return getValidKeys().then(function (result) {
if (_.has(result, options.key)) {
return { 'configuration': [{
key: options.key,
value: result[options.key]
}]};
} else {
return Promise.reject(new errors.NotFoundError('Invalid key'));
}
});
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to read the configuration.'));
});
}
};
module.exports = configuration;

View File

@ -8,6 +8,7 @@ var _ = require('lodash'),
Promise = require('bluebird'),
config = require('../config'),
// Include Endpoints
configuration = require('./configuration'),
db = require('./db'),
mail = require('./mail'),
notifications = require('./notifications'),
@ -278,6 +279,7 @@ module.exports = {
init: init,
http: http,
// API Endpoints
configuration: configuration,
db: db,
mail: mail,
notifications: notifications,

View File

@ -1,5 +1,15 @@
{
"permissions": {
"configuration": [
{
"name": "Browse configuration",
"action_type": "browse"
},
{
"name": "Read configuration",
"action_type": "read"
}
],
"db": [
{
"name": "Export database",
@ -143,6 +153,7 @@
},
"permissions_roles": {
"Administrator": {
"configuration": "all",
"db": "all",
"mail": "all",
"notification": "all",
@ -155,6 +166,7 @@
"role": "all"
},
"Editor": {
"configuration": "all",
"post": "all",
"setting": ["browse", "read"],
"slug": "all",
@ -164,6 +176,7 @@
"role": "all"
},
"Author": {
"configuration": "all",
"post": ["browse", "read", "add"],
"setting": ["browse", "read"],
"slug": "all",

View File

@ -8,6 +8,10 @@ apiRoutes = function (middleware) {
// alias delete with del
router.del = router.delete;
// ## Configuration
router.get('/configuration', api.http(api.configuration.browse));
router.get('/configuration/:key', api.http(api.configuration.read));
// ## Posts
router.get('/posts', api.http(api.posts.browse));
router.post('/posts', api.http(api.posts.add));

View File

@ -0,0 +1,75 @@
/*globals describe, before, beforeEach, afterEach, it */
/*jshint expr:true*/
var testUtils = require('../../utils'),
should = require('should'),
sinon = require('sinon'),
rewire = require('rewire'),
_ = require('lodash'),
config = rewire('../../../server/config'),
// Stuff we are testing
ConfigurationAPI = rewire('../../../server/api/configuration');
describe('Configuration API', function () {
var newConfig = {
'fileStorage': true,
'apps': true,
'version': '0.5.0',
'environment': process.env.NODE_ENV,
'database': {
'client': 'mysql'
},
'mail': {
'transport': 'SMTP'
},
'blogUrl': 'http://local.tryghost.org'
};
// Keep the DB clean
before(testUtils.teardown);
afterEach(testUtils.teardown);
beforeEach(testUtils.setup('users','users:roles', 'perms:user', 'perms:role', 'perms:configuration', 'perms:init'));
should.exist(ConfigurationAPI);
it('can browse config', function (done) {
var existingConfig = ConfigurationAPI.__get__('config'),
updatedConfig = _.extend(config, newConfig);
config.set(updatedConfig);
ConfigurationAPI.__set__('config', updatedConfig);
ConfigurationAPI.browse(testUtils.context.owner).then(function (response) {
should.exist(response);
should.exist(response.configuration);
testUtils.API.checkResponse(response.configuration[0], 'configuration');
/*jshint unused:false */
done();
}).catch(function (error) {
console.log(JSON.stringify(error));
done();
}).catch(done);
});
it('can read config', function (done) {
var existingConfig = ConfigurationAPI.__get__('config'),
updatedConfig = _.extend(config, newConfig);
config.set(updatedConfig);
ConfigurationAPI.__set__('config', updatedConfig);
ConfigurationAPI.read(_.extend(testUtils.context.owner, { key: 'database' })).then(function (response) {
should.exist(response);
should.exist(response.configuration);
testUtils.API.checkResponse(response.configuration[0], 'configuration');
response.configuration[0].key.should.equal('database');
response.configuration[0].value.should.equal('mysql');
/*jshint unused:false */
done();
}).catch(function (error) {
console.log(JSON.stringify(error));
done();
}).catch(done);
});
});

View File

@ -6,6 +6,7 @@ var url = require('url'),
port = config.server.port,
schema = 'http://',
expectedProperties = {
configuration: ['key', 'value'],
posts: ['posts', 'meta'],
users: ['users', 'meta'],
roles: ['roles'],