From 33d0f686beabc5002b59a5f31a99160b6b948654 Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Wed, 16 Jun 2021 13:58:08 +0100 Subject: [PATCH] Extracted Bookshelf user type code into plugin no issue - this commit extracts the code relating to detecting if a user ID is internal/external from the Base model into a separate plugin --- core/server/models/base/bookshelf.js | 2 + core/server/models/base/index.js | 89 -------------------------- core/server/models/base/user-type.js | 94 ++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 89 deletions(-) create mode 100644 core/server/models/base/user-type.js diff --git a/core/server/models/base/bookshelf.js b/core/server/models/base/bookshelf.js index 4b9518273f..8e6ba95eac 100644 --- a/core/server/models/base/bookshelf.js +++ b/core/server/models/base/bookshelf.js @@ -58,6 +58,8 @@ ghostBookshelf.plugin(require('./bulk-operations')); ghostBookshelf.plugin(require('./filtered-collection')); +ghostBookshelf.plugin(require('./user-type')); + // Manages nested updates (relationships) ghostBookshelf.plugin('bookshelf-relations', { allowedOptions: ['context', 'importing', 'migrating'], diff --git a/core/server/models/base/index.js b/core/server/models/base/index.js index 5dc527fb90..8a2dec5c0d 100644 --- a/core/server/models/base/index.js +++ b/core/server/models/base/index.js @@ -10,17 +10,10 @@ const _ = require('lodash'); const moment = require('moment'); const ObjectId = require('bson-objectid'); -const errors = require('@tryghost/errors'); const schema = require('../../data/schema'); -const bulkOperations = require('./bulk-operations'); -const tpl = require('@tryghost/tpl'); const ghostBookshelf = require('./bookshelf'); -const messages = { - missingContext: 'missing context' -}; - let proto; // Cache an instance of the base model prototype @@ -160,70 +153,6 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({ }); }, - getActor(options = {context: {}}) { - if (options.context && options.context.integration) { - return { - id: options.context.integration.id, - type: 'integration' - }; - } - - if (options.context && options.context.user) { - return { - id: options.context.user, - type: 'user' - }; - } - - return null; - }, - - // Get the user from the options object - contextUser: function contextUser(options) { - options = options || {}; - options.context = options.context || {}; - - if (options.context.user || ghostBookshelf.Model.isExternalUser(options.context.user)) { - return options.context.user; - } else if (options.context.integration) { - /** - * @NOTE: - * - * This is a dirty hotfix for v0.1 only. - * The `x_by` columns are getting deprecated soon (https://github.com/TryGhost/Ghost/issues/10286). - * - * We return the owner ID '1' in case an integration updates or creates - * resources. v0.1 will continue to use the `x_by` columns. v0.1 does not support integrations. - * API v2 will introduce a new feature to solve inserting/updating resources - * from users or integrations. API v2 won't expose `x_by` columns anymore. - * - * --- - * - * Why using ID '1'? WAIT. What??????? - * - * See https://github.com/TryGhost/Ghost/issues/9299. - * - * We currently don't read the correct owner ID from the database and assume it's '1'. - * This is a leftover from switching from auto increment ID's to Object ID's. - * But this takes too long to refactor out now. If an internal update happens, we also - * use ID '1'. This logic exists for a LONG while now. The owner ID only changes from '1' to something else, - * if you transfer ownership. - */ - return ghostBookshelf.Model.internalUser; - } else if (options.context.internal) { - return ghostBookshelf.Model.internalUser; - } else if (this.get('id')) { - return this.get('id'); - } else if (options.context.external) { - return ghostBookshelf.Model.externalUser; - } else { - throw new errors.NotFoundError({ - message: tpl(messages.missingContext), - level: 'critical' - }); - } - }, - // format date before writing to DB, bools work format: function format(attrs) { return this.fixDatesWhenSave(attrs); @@ -310,24 +239,6 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({ return true; } -}, { - // ## Data Utility Functions - - /** - * please use these static definitions when comparing id's - * we keep type Number, because we have too many check's where we rely on Number - * context.user ? true : false (if context.user is 0 as number, this condition is false) - */ - internalUser: 1, - externalUser: 0, - - isInternalUser: function isInternalUser(id) { - return id === ghostBookshelf.Model.internalUser || id === ghostBookshelf.Model.internalUser.toString(); - }, - - isExternalUser: function isExternalUser(id) { - return id === ghostBookshelf.Model.externalUser || id === ghostBookshelf.Model.externalUser.toString(); - } }); // Export ghostBookshelf for use elsewhere diff --git a/core/server/models/base/user-type.js b/core/server/models/base/user-type.js new file mode 100644 index 0000000000..aea28206c4 --- /dev/null +++ b/core/server/models/base/user-type.js @@ -0,0 +1,94 @@ +const errors = require('@tryghost/errors'); +const tpl = require('@tryghost/tpl'); + +const messages = { + missingContext: 'missing context' +}; + +/** + * @param {import('bookshelf')} Bookshelf + */ +module.exports = function (Bookshelf) { + Bookshelf.Model = Bookshelf.Model.extend({ + getActor(options = {context: {}}) { + if (options.context && options.context.integration) { + return { + id: options.context.integration.id, + type: 'integration' + }; + } + + if (options.context && options.context.user) { + return { + id: options.context.user, + type: 'user' + }; + } + + return null; + }, + + // Get the user from the options object + contextUser: function contextUser(options) { + options = options || {}; + options.context = options.context || {}; + + if (options.context.user || Bookshelf.Model.isExternalUser(options.context.user)) { + return options.context.user; + } else if (options.context.integration) { + /** + * @NOTE: + * + * This is a dirty hotfix for v0.1 only. + * The `x_by` columns are getting deprecated soon (https://github.com/TryGhost/Ghost/issues/10286). + * + * We return the owner ID '1' in case an integration updates or creates + * resources. v0.1 will continue to use the `x_by` columns. v0.1 does not support integrations. + * API v2 will introduce a new feature to solve inserting/updating resources + * from users or integrations. API v2 won't expose `x_by` columns anymore. + * + * --- + * + * Why using ID '1'? WAIT. What??????? + * + * See https://github.com/TryGhost/Ghost/issues/9299. + * + * We currently don't read the correct owner ID from the database and assume it's '1'. + * This is a leftover from switching from auto increment ID's to Object ID's. + * But this takes too long to refactor out now. If an internal update happens, we also + * use ID '1'. This logic exists for a LONG while now. The owner ID only changes from '1' to something else, + * if you transfer ownership. + */ + return Bookshelf.Model.internalUser; + } else if (options.context.internal) { + return Bookshelf.Model.internalUser; + } else if (this.get('id')) { + return this.get('id'); + } else if (options.context.external) { + return Bookshelf.Model.externalUser; + } else { + throw new errors.NotFoundError({ + message: tpl(messages.missingContext), + level: 'critical' + }); + } + } + }, { + /** + * please use these static definitions when comparing id's + * we keep type Number, because we have too many check's where we rely on Number + * context.user ? true : false (if context.user is 0 as number, this condition is false) + */ + internalUser: 1, + externalUser: 0, + + isInternalUser: function isInternalUser(id) { + return id === Bookshelf.Model.internalUser || id === Bookshelf.Model.internalUser.toString(); + }, + + isExternalUser: function isExternalUser(id) { + return id === Bookshelf.Model.externalUser || id === Bookshelf.Model.externalUser.toString(); + } + + }); +};