0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-17 23:44:39 -05:00

Added allowlist limit (#144)

issue https://github.com/TryGhost/Team/issues/510
This commit is contained in:
Thibaut Patel 2021-04-08 17:29:53 +02:00 committed by GitHub
parent 8c6ec8b214
commit 8381346dce
3 changed files with 88 additions and 10 deletions

View file

@ -1,4 +1,4 @@
const {MaxLimit, FlagLimit} = require('./limit');
const {MaxLimit, FlagLimit, AllowlistLimit} = require('./limit');
const config = require('./config');
const _ = require('lodash');
@ -30,7 +30,9 @@ class LimitService {
/** @type LimitConfig */
let limitConfig = Object.assign({}, config[name], limits[name]);
if (_.has(limitConfig, 'max')) {
if (_.has(limitConfig, 'allowlist')) {
this.limits[name] = new AllowlistLimit({name, config: limitConfig, helpLink, errors});
} else if (_.has(limitConfig, 'max')) {
this.limits[name] = new MaxLimit({name: name, config: limitConfig, helpLink, db, errors});
} else {
this.limits[name] = new FlagLimit({name: name, config: limitConfig, helpLink, errors});
@ -58,13 +60,13 @@ class LimitService {
}
}
async checkWouldGoOverLimit(limitName) {
async checkWouldGoOverLimit(limitName, metadata = {}) {
if (!this.isLimited(limitName)) {
return;
}
try {
await this.limits[limitName].errorIfWouldGoOverLimit();
await this.limits[limitName].errorIfWouldGoOverLimit(metadata);
return false;
} catch (error) {
if (error instanceof this.errors.HostLimitError) {
@ -73,20 +75,20 @@ class LimitService {
}
}
async errorIfIsOverLimit(limitName) {
async errorIfIsOverLimit(limitName, metadata = {}) {
if (!this.isLimited(limitName)) {
return;
}
await this.limits[limitName].errorIfIsOverLimit();
await this.limits[limitName].errorIfIsOverLimit(metadata);
}
async errorIfWouldGoOverLimit(limitName) {
async errorIfWouldGoOverLimit(limitName, metadata = {}) {
if (!this.isLimited(limitName)) {
return;
}
await this.limits[limitName].errorIfWouldGoOverLimit();
await this.limits[limitName].errorIfWouldGoOverLimit(metadata);
}
}

View file

@ -157,7 +157,51 @@ class FlagLimit extends Limit {
}
}
class AllowlistLimit extends Limit {
constructor({name, config, helpLink, errors}) {
super({name, error: config.error || '', helpLink, errors});
if (!config.allowlist || !config.allowlist.length) {
throw new this.errors.IncorrectUsageError('Attempted to setup an allowlist limit without an allowlist');
}
this.allowlist = config.allowlist;
this.fallbackMessage = `This action would exceed the ${_.lowerCase(this.name)} limit on your current plan.`;
}
generateError() {
let errorObj = super.generateError();
if (this.error) {
errorObj.message = this.error;
} else {
errorObj.message = this.fallbackMessage;
}
return new this.errors.HostLimitError(errorObj);
}
async errorIfWouldGoOverLimit(metadata) {
if (!metadata.value) {
throw new this.errors.IncorrectUsageError('Attempted to check an allowlist limit without a value');
}
if (!this.allowlist.includes(metadata.value)) {
throw this.generateError();
}
}
async errorIfIsOverLimit(metadata) {
if (!metadata.value) {
throw new this.errors.IncorrectUsageError('Attempted to check an allowlist limit without a value');
}
if (!this.allowlist.includes(metadata.value)) {
throw this.generateError();
}
}
}
module.exports = {
MaxLimit,
FlagLimit
FlagLimit,
AllowlistLimit
};

View file

@ -3,7 +3,7 @@
require('./utils');
const errors = require('./fixtures/errors');
const {MaxLimit} = require('../lib/limit');
const {MaxLimit, AllowlistLimit} = require('../lib/limit');
describe('Limit Service', function () {
describe('Max Limit', function () {
@ -167,4 +167,36 @@ describe('Limit Service', function () {
});
});
});
describe('Allowlist limit', function () {
it('rejects when the allowlist config isn\'t specified', async function () {
try {
new AllowlistLimit({name: 'test', config: {}, errors});
throw new Error('Should have failed earlier...');
} catch (error) {
error.errorType.should.equal('IncorrectUsageError');
}
});
it('accept correct values', async function () {
const limit = new AllowlistLimit({name: 'test', config: {
allowlist: ['test', 'ok']
}, errors});
await limit.errorIfIsOverLimit({value: 'test'});
});
it('rejects unkown values', async function () {
const limit = new AllowlistLimit({name: 'test', config: {
allowlist: ['test', 'ok']
}, errors});
try {
await limit.errorIfIsOverLimit({value: 'unkown value'});
throw new Error('Should have failed earlier...');
} catch (error) {
error.errorType.should.equal('HostLimitError');
}
});
});
});