diff --git a/core/server/models/base/index.js b/core/server/models/base/index.js index 4c34db16c6..0396a99255 100644 --- a/core/server/models/base/index.js +++ b/core/server/models/base/index.js @@ -30,9 +30,6 @@ ghostBookshelf = bookshelf(db.knex); // Load the Bookshelf registry plugin, which helps us avoid circular dependencies ghostBookshelf.plugin('registry'); -// Load the Ghost access rules plugin, which handles passing permissions/context through the model layer -ghostBookshelf.plugin(plugins.accessRules); - // Load the Ghost filter plugin, which handles applying a 'filter' to findPage requests ghostBookshelf.plugin(plugins.filter); diff --git a/core/server/models/plugins/access-rules.js b/core/server/models/plugins/access-rules.js deleted file mode 100644 index 49eb3c553d..0000000000 --- a/core/server/models/plugins/access-rules.js +++ /dev/null @@ -1,50 +0,0 @@ -// # Access Rules -// -// Extends Bookshelf.Model.forge to take a 'context' option which provides information on how this query should -// be treated in terms of data access rules - currently just detecting public requests -module.exports = function (Bookshelf) { - var model = Bookshelf.Model, - Model; - - Model = Bookshelf.Model.extend({ - /** - * Cached copy of the context setup for this model instance - */ - _context: null, - - /** - * ## Is Public Context? - * A helper to determine if this is a public request or not - * @returns {boolean} - */ - isPublicContext: function isPublicContext() { - return !!(this._context && this._context.public); - }, - - isInternalContext: function isInternalContext() { - return !!(this._context && this._context.internal); - } - }, - { - /** - * ## Forge - * Ensure that context gets set as part of the forge - * - * @param {object} attributes - * @param {object} options - * @returns {Bookshelf.Model} model - */ - forge: function forge(attributes, options) { - var self = model.forge.apply(this, arguments); - - if (options && options.context) { - self._context = options.context; - delete options.context; - } - - return self; - } - }); - - Bookshelf.Model = Model; -}; diff --git a/core/server/models/plugins/filter.js b/core/server/models/plugins/filter.js index 9a81484928..09112ba6c4 100644 --- a/core/server/models/plugins/filter.js +++ b/core/server/models/plugins/filter.js @@ -145,8 +145,8 @@ filter = function filter(Bookshelf) { options = options || {}; this._filters = filterUtils.combineFilters( - this.enforcedFilters(), - this.defaultFilters(), + this.enforcedFilters(options), + this.defaultFilters(options), options.filter, options.where ); diff --git a/core/server/models/plugins/include-count.js b/core/server/models/plugins/include-count.js index 4b3b6538b9..5efea83d01 100644 --- a/core/server/models/plugins/include-count.js +++ b/core/server/models/plugins/include-count.js @@ -9,7 +9,7 @@ module.exports = function (Bookshelf) { countQueryBuilder = { tags: { - posts: function addPostCountToTags(model) { + posts: function addPostCountToTags(model, options) { model.query('columns', 'tags.*', function (qb) { qb.count('posts.id') .from('posts') @@ -17,7 +17,7 @@ module.exports = function (Bookshelf) { .whereRaw('posts_tags.tag_id = tags.id') .as('count__posts'); - if (model.isPublicContext()) { + if (options.context && options.context.public) { // @TODO use the filter behavior for posts qb.andWhere('posts.page', '=', false); qb.andWhere('posts.status', '=', 'published'); @@ -26,14 +26,14 @@ module.exports = function (Bookshelf) { } }, users: { - posts: function addPostCountToTags(model) { + posts: function addPostCountToTags(model, options) { model.query('columns', 'users.*', function (qb) { qb.count('posts.id') .from('posts') .whereRaw('posts.author_id = users.id') .as('count__posts'); - if (model.isPublicContext()) { + if (options.context && options.context.public) { // @TODO use the filter behavior for posts qb.andWhere('posts.page', '=', false); qb.andWhere('posts.status', '=', 'published'); @@ -56,7 +56,7 @@ module.exports = function (Bookshelf) { options.withRelated = _.pull([].concat(options.withRelated), 'count.posts'); // Call the query builder - countQueryBuilder[tableName].posts(this); + countQueryBuilder[tableName].posts(this, options); } }, fetch: function () { diff --git a/core/server/models/plugins/index.js b/core/server/models/plugins/index.js index c168a4449f..9dc6dddbcc 100644 --- a/core/server/models/plugins/index.js +++ b/core/server/models/plugins/index.js @@ -1,5 +1,4 @@ module.exports = { - accessRules: require('./access-rules'), filter: require('./filter'), includeCount: require('./include-count'), pagination: require('./pagination'), diff --git a/core/server/models/post.js b/core/server/models/post.js index f9380b8886..32c2166754 100644 --- a/core/server/models/post.js +++ b/core/server/models/post.js @@ -401,15 +401,15 @@ Post = ghostBookshelf.Model.extend({ return attrs; }, - enforcedFilters: function enforcedFilters() { - return this.isPublicContext() ? 'status:published' : null; + enforcedFilters: function enforcedFilters(options) { + return options.context && options.context.public ? 'status:published' : null; }, - defaultFilters: function defaultFilters() { - if (this.isInternalContext()) { + defaultFilters: function defaultFilters(options) { + if (options.context && options.context.internal) { return null; } - return this.isPublicContext() ? 'page:false' : 'page:false+status:published'; + return options.context && options.context.public ? 'page:false' : 'page:false+status:published'; } }, { allowedFormats: ['mobiledoc', 'html', 'plaintext', 'amp'], diff --git a/core/server/models/user.js b/core/server/models/user.js index 94663b12e3..f480a22ae4 100644 --- a/core/server/models/user.js +++ b/core/server/models/user.js @@ -261,20 +261,20 @@ User = ghostBookshelf.Model.extend({ }); }, - enforcedFilters: function enforcedFilters() { - if (this.isInternalContext()) { + enforcedFilters: function enforcedFilters(options) { + if (options.context && options.context.internal) { return null; } - return this.isPublicContext() ? 'status:[' + allStates.join(',') + ']' : null; + return options.context && options.context.public ? 'status:[' + allStates.join(',') + ']' : null; }, - defaultFilters: function defaultFilters() { - if (this.isInternalContext()) { + defaultFilters: function defaultFilters(options) { + if (options.context && options.context.internal) { return null; } - return this.isPublicContext() ? null : 'status:[' + allStates.join(',') + ']'; + return options.context && options.context.public ? null : 'status:[' + allStates.join(',') + ']'; } }, { orderDefaultOptions: function orderDefaultOptions() { diff --git a/core/test/unit/models/plugins/access-rules_spec.js b/core/test/unit/models/plugins/access-rules_spec.js deleted file mode 100644 index 2786e69bc4..0000000000 --- a/core/test/unit/models/plugins/access-rules_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -var should = require('should'), // jshint ignore:line - sinon = require('sinon'), - -// Thing we're testing - models = require('../../../../server/models'), - ghostBookshelf, - - sandbox = sinon.sandbox.create(); - -describe('Access Rules', function () { - beforeEach(function () { - models.init(); - ghostBookshelf = models.Base; - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('Base Model', function () { - it('should assign isPublicContext to prototype', function () { - ghostBookshelf.Model.prototype.isPublicContext.should.be.a.Function(); - }); - - it('should get called when a model is forged', function () { - ghostBookshelf.Model.forge(null, {context: 'test'})._context.should.eql('test'); - }); - - describe('isPublicContext', function () { - it('should isPublicContext false if no context is set', function () { - ghostBookshelf.Model.forge().isPublicContext().should.be.false(); - }); - - it('should return false if context has no `public` property', function () { - ghostBookshelf.Model.forge(null, {context: 'test'}).isPublicContext().should.be.false(); - }); - - it('should return false if context.public is false', function () { - ghostBookshelf.Model.forge(null, {context: {public: false}}).isPublicContext().should.be.false(); - }); - - it('should return true if context.public is true', function () { - ghostBookshelf.Model.forge(null, {context: {public: true}}).isPublicContext().should.be.true(); - }); - }); - }); -});