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:
parent
8c6ec8b214
commit
8381346dce
3 changed files with 88 additions and 10 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue