From 40cedb84ff20b971c0c3dc76dcf6ad19817c2857 Mon Sep 17 00:00:00 2001 From: Naz Date: Thu, 8 Apr 2021 16:59:56 +1200 Subject: [PATCH] Added integration with limit service refs https://github.com/TryGhost/Team/issues/587 - This is first pass on the frontend limit-service integration. Max count queries are substituted with HTTP requests to mimick backend checks. Note, they are not meant to substitute backend checks only to suplment them. --- ghost/admin/app/services/limit.js | 86 +++++++++++++++++++ ghost/admin/package.json | 1 + ghost/admin/tests/unit/services/limit-test.js | 17 ++++ ghost/admin/yarn.lock | 12 +++ 4 files changed, 116 insertions(+) create mode 100644 ghost/admin/app/services/limit.js create mode 100644 ghost/admin/tests/unit/services/limit-test.js diff --git a/ghost/admin/app/services/limit.js b/ghost/admin/app/services/limit.js new file mode 100644 index 0000000000..2412bb1390 --- /dev/null +++ b/ghost/admin/app/services/limit.js @@ -0,0 +1,86 @@ +import LimitService from '@tryghost/limit-service'; +import RSVP from 'rsvp'; +import Service, {inject as service} from '@ember/service'; +import {bind} from '@ember/runloop'; + +class LimitError { + constructor({errorType, errorDetails, message}) { + this.errorType = errorType; + this.errorDetails = errorDetails; + this.message = message; + } +} + +class IncorrectUsageError extends LimitError { + constructor(options) { + super(Object.assign({errorType: 'IncorrectUsageError'}, options)); + } +} + +class HostLimitError extends LimitError { + constructor(options) { + super(Object.assign({errorType: 'HostLimitError'}, options)); + } +} + +export default class LimitsService extends Service { + @service config; + @service store; + @service membersStats; + + constructor() { + super(...arguments); + + let limits = this.config.get('hostSettings.limits'); + + if (limits && !this.limiter) { + this.limiter = new LimitService(); + + let helpLink; + + if (this.config.get('hostSettings.billing.enabled') + && this.config.get('hostSettings.billing.enabled') === true + && this.config.get('hostSettings.billing.url')) { + helpLink = this.config.get('hostSettings.billing.url'); + } else { + helpLink = 'https://ghost.org/help/'; + } + + return this.limiter.loadLimits({ + limits: this.decorateWithCountQueries(limits), + helpLink, + errors: { + HostLimitError, + IncorrectUsageError + } + }); + } + } + + decorateWithCountQueries(limits) { + if (limits.staff) { + limits.staff.currentCountQuery = bind(this, this.getStaffUsersCount); + } + + if (limits.members) { + limits.members.currentCountQuery = bind(this, this.getMembersCount); + } + + return limits; + } + + async getStaffUsersCount() { + return RSVP.hash({ + users: this.store.findAll('user', {reload: true}), + invites: this.store.findAll('invite', {reload: true}) + }).then((data) => { + return data.users.length + data.invites.length; + }); + } + + async getMembersCount() { + const counts = await this.membersStats.fetchCounts(); + + return counts.total; + } +} diff --git a/ghost/admin/package.json b/ghost/admin/package.json index 6a66f9742f..a20f8980ca 100644 --- a/ghost/admin/package.json +++ b/ghost/admin/package.json @@ -33,6 +33,7 @@ "@tryghost/helpers": "1.1.37", "@tryghost/kg-clean-basic-html": "1.0.11", "@tryghost/kg-parser-plugins": "1.1.0", + "@tryghost/limit-service": "0.4.0", "@tryghost/members-csv": "0.4.2", "@tryghost/mobiledoc-kit": "0.12.5-ghost.1", "@tryghost/string": "0.1.16", diff --git a/ghost/admin/tests/unit/services/limit-test.js b/ghost/admin/tests/unit/services/limit-test.js new file mode 100644 index 0000000000..222f51cf7f --- /dev/null +++ b/ghost/admin/tests/unit/services/limit-test.js @@ -0,0 +1,17 @@ +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import {setupTest} from 'ember-mocha'; + +describe('Unit | Service | limit', function () { + setupTest(); + + let limitService; + + beforeEach(function () { + limitService = this.owner.lookup('service:limit'); + }); + + it('exists', function () { + expect(limitService).to.be.ok; + }); +}); diff --git a/ghost/admin/yarn.lock b/ghost/admin/yarn.lock index 1eb73b0d7f..ac88b0a5a3 100644 --- a/ghost/admin/yarn.lock +++ b/ghost/admin/yarn.lock @@ -1760,6 +1760,13 @@ dependencies: "@tryghost/kg-clean-basic-html" "^1.0.11" +"@tryghost/limit-service@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@tryghost/limit-service/-/limit-service-0.4.0.tgz#a681eb866171a6966162db87ae0d18ccb1fbb965" + integrity sha512-DVWYiKgvXzWqi+L2jJPhTQLogiRZUJw+bX9XMmLg202rnNAn8A9eYIAmWu5TbY4Gp0+6gz6IZFdIIocGDtA8Aw== + dependencies: + lodash "^4.17.21" + "@tryghost/members-csv@0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@tryghost/members-csv/-/members-csv-0.4.2.tgz#af6189ea30a18b7ebe1f67c442d459ea8ef7aff9" @@ -10287,6 +10294,11 @@ lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17. resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"