mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-30 21:40:39 +03:00
9d7c3bd726
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16 - removed GQL dependency - replaced GQL with our brand new NQL implementation - fixed all known filter limitations - GQL suffered from some underlying filter bugs, which NQL tried to fix - the bugs were mostly in how we query the database for relation filtering - the underlying problem was caused by a too simple implementation of querying the relations - mongo-knex has implemented a more robust and complex filtering mechanism for relations - replaced logic in our bookshelf filter plugin - we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex. NQL: https://github.com/NexesJS/NQL mongo-knex: https://github.com/NexesJS/mongo-knex
73 lines
2.3 KiB
JavaScript
73 lines
2.3 KiB
JavaScript
var _ = require('lodash'),
|
|
Promise = require('bluebird'),
|
|
common = require('../../lib/common'),
|
|
parseContext = require('./parse-context'),
|
|
_private = {};
|
|
|
|
/**
|
|
* @TODO:
|
|
*
|
|
* - remove if we drop `extraFilters` (see e.g. post model)
|
|
* - we currently accept `?status={value}` in the API
|
|
* - we currently accept `?staticPages={value}` in the API
|
|
* - but instead people should use the `?filter=status:{value}`
|
|
*
|
|
* This function protects against:
|
|
*
|
|
* - public context cannot fetch draft/scheduled posts
|
|
*/
|
|
_private.applyStatusRules = function applyStatusRules(docName, method, opts) {
|
|
var err = new common.errors.NoPermissionError({message: common.i18n.t('errors.permissions.applyStatusRules.error', {docName: docName})});
|
|
|
|
// Enforce status 'active' for users
|
|
if (docName === 'users') {
|
|
if (!opts.status) {
|
|
return 'all';
|
|
}
|
|
}
|
|
|
|
// Enforce status 'published' for posts
|
|
if (docName === 'posts') {
|
|
if (!opts.status) {
|
|
return 'published';
|
|
} else if (
|
|
method === 'read'
|
|
&& (opts.status === 'draft' || opts.status === 'all')
|
|
&& _.isString(opts.uuid) && _.isUndefined(opts.id) && _.isUndefined(opts.slug)
|
|
) {
|
|
// public read requests can retrieve a draft, but only by UUID
|
|
return opts.status;
|
|
} else if (opts.status !== 'published') {
|
|
// any other parameter would make this a permissions error
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
return opts.status;
|
|
};
|
|
|
|
/**
|
|
* API Public Permission Rules
|
|
* This method enforces the rules for public requests
|
|
* @param {String} docName
|
|
* @param {String} method (read || browse)
|
|
* @param {Object} options
|
|
* @returns {Object} options
|
|
*/
|
|
module.exports = function applyPublicRules(docName, method, options) {
|
|
try {
|
|
// If this is a public context
|
|
if (parseContext(options.context).public === true) {
|
|
if (method === 'browse') {
|
|
options.status = _private.applyStatusRules(docName, method, options);
|
|
} else if (method === 'read') {
|
|
options.data.status = _private.applyStatusRules(docName, method, options.data);
|
|
}
|
|
}
|
|
|
|
return Promise.resolve(options);
|
|
} catch (err) {
|
|
return Promise.reject(err);
|
|
}
|
|
};
|