From eebfbfd636b8bf77c1f6949752b1860d498b9ceb Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Sun, 10 Oct 2021 19:58:41 +0200 Subject: [PATCH] Refactored tabletop methods --- .../api/creature/creatures/Creatures.js | 29 ---- app/imports/api/tabletop/Tabletops.js | 150 ------------------ .../methods/addCreaturesToTabletop.js | 57 +++++++ .../api/tabletop/methods/insertTabletop.js | 34 ++++ .../api/tabletop/methods/removeTabletop.js | 49 ++++++ .../methods/shared/tabletopPermissions.js | 25 +++ app/imports/api/users/Users.js | 6 - 7 files changed, 165 insertions(+), 185 deletions(-) create mode 100644 app/imports/api/tabletop/methods/addCreaturesToTabletop.js create mode 100644 app/imports/api/tabletop/methods/insertTabletop.js create mode 100644 app/imports/api/tabletop/methods/removeTabletop.js create mode 100644 app/imports/api/tabletop/methods/shared/tabletopPermissions.js diff --git a/app/imports/api/creature/creatures/Creatures.js b/app/imports/api/creature/creatures/Creatures.js index f4a07dba..43762c81 100644 --- a/app/imports/api/creature/creatures/Creatures.js +++ b/app/imports/api/creature/creatures/Creatures.js @@ -100,35 +100,6 @@ let CreatureSchema = new SimpleSchema({ type: SimpleSchema.Integer, defaultValue: 0, }, - // Inventory - 'denormalizedStats.weightTotal': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.weightEquipment': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.weightCarried': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.valueTotal': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.valueEquipment': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.valueCarried': { - type: Number, - defaultValue: 0, - }, - 'denormalizedStats.itemsAttuned': { - type: Number, - defaultValue: 0, - }, // Version of computation engine that was last used to compute this creature computeVersion: { type: String, diff --git a/app/imports/api/tabletop/Tabletops.js b/app/imports/api/tabletop/Tabletops.js index cf991b55..59ad1de9 100644 --- a/app/imports/api/tabletop/Tabletops.js +++ b/app/imports/api/tabletop/Tabletops.js @@ -1,8 +1,4 @@ import SimpleSchema from 'simpl-schema'; -import { ValidatedMethod } from 'meteor/mdg:validated-method'; -import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; -import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js'; -import Creatures from '/imports/api/creature/creatures/Creatures.js'; let Tabletops = new Mongo.Collection('tabletops'); @@ -52,150 +48,4 @@ let TabletopSchema = new SimpleSchema({ Tabletops.attachSchema(TabletopSchema); -function assertUserIsTabletopOwner(tabletopId, userId){ - let tabletop = Tabletops.findOne(tabletopId); - if (!tabletop){ - throw new Meteor.Error('Tabletop does not exist', - 'No tabletop could be found for the given tabletop id'); - } - if (tabletop.gameMaster !== userId){ - throw new Meteor.Error('Not the owner', - 'The user is not the owner of the given tabletop'); - } -} - -export function assertUserInTabletop(tabletopId, userId){ - let tabletop = Tabletops.findOne(tabletopId); - if (!tabletop){ - throw new Meteor.Error('Tabletop does not exist', - 'No tabletop could be found for the given tabletop id'); - } - if (tabletop.gameMaster !== userId && !tabletop.players.includes(userId)){ - throw new Meteor.Error('Not in tabletop', - 'The user is not the gamemaster or a player in the given tabletop'); - } -} - -function assertUserIsAdmin(userId){ - if (!Meteor.users.isAdmin(userId)){ - throw new Meteor.Error('Admin only', - 'This is restricted to admins for now'); - } -} - -const insertTabletop = new ValidatedMethod({ - - name: 'tabletops.insert', - - validate: null, - - mixins: [RateLimiterMixin], - rateLimit: { - numRequests: 5, - timeInterval: 5000, - }, - - run() { - if (!this.userId) { - throw new Meteor.Error('tabletops.insert.denied', - 'You need to be logged in to insert a tabletop'); - } - assertUserHasPaidBenefits(this.userId); - assertUserIsAdmin(this.userId); - - return Tabletops.insert({ - gameMaster: this.userId, - }); - }, - -}); - -const removeTabletop = new ValidatedMethod({ - - name: 'tabletops.remove', - - validate: new SimpleSchema({ - tabletopId: { - type: String, - regEx: SimpleSchema.RegEx.id, - }, - }).validator(), - - mixins: [RateLimiterMixin], - rateLimit: { - numRequests: 5, - timeInterval: 5000, - }, - - run({tabletopId}) { - if (!this.userId) { - throw new Meteor.Error('tabletops.remove.denied', - 'You need to be logged in to remove a tabletop'); - } - assertUserHasPaidBenefits(this.userId); - assertUserIsTabletopOwner(tabletopId, this.userId); - assertUserIsAdmin(this.userId); - - let removed = Tabletops.remove({ - _id: tabletopId, - }); - Creatures.update({ - tabletop: tabletopId, - }, { - $unset: {tabletop: 1}, - }); - return removed; - }, - -}); - -const addCreaturesToTabletop = new ValidatedMethod({ - - name: 'tabletops.addCreatures', - - validate: new SimpleSchema({ - 'creatureIds': { - type: Array, - }, - 'creatureIds.$': { - type: String, - regEx: SimpleSchema.RegEx.id, - }, - tabletopId: { - type: String, - regEx: SimpleSchema.RegEx.id, - }, - }).validator(), - - mixins: [RateLimiterMixin], - rateLimit: { - numRequests: 10, - timeInterval: 5000, - }, - - run({tabletopId, creatureIds}) { - if (!this.userId) { - throw new Meteor.Error('tabletops.addCreatures.denied', - 'You need to be logged in to remove a tabletop'); - } - assertUserHasPaidBenefits(this.userId); - assertUserInTabletop(tabletopId, this.userId); - assertUserIsAdmin(this.userId); - - Creatures.update({ - _id: {$in: creatureIds}, - $or: [ - {writers: this.userId}, - {owner: this.userId}, - ], - }, { - $set: {tabletop: tabletopId}, - }, { - multi: true, - }); - }, - -}); - export default Tabletops; -export { insertTabletop, removeTabletop, addCreaturesToTabletop }; diff --git a/app/imports/api/tabletop/methods/addCreaturesToTabletop.js b/app/imports/api/tabletop/methods/addCreaturesToTabletop.js new file mode 100644 index 00000000..b17b953b --- /dev/null +++ b/app/imports/api/tabletop/methods/addCreaturesToTabletop.js @@ -0,0 +1,57 @@ +import SimpleSchema from 'simpl-schema'; +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; +import { assertUserInTabletop } from './shared/tabletopPermissions.js'; +import { assertAdmin } from '/imports/api/sharing/sharingPermissions.js'; +import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js'; +import Creatures from '/imports/api/creature/creatures/Creatures.js'; + +const addCreaturesToTabletop = new ValidatedMethod({ + + name: 'tabletops.addCreatures', + + validate: new SimpleSchema({ + 'creatureIds': { + type: Array, + }, + 'creatureIds.$': { + type: String, + regEx: SimpleSchema.RegEx.id, + }, + tabletopId: { + type: String, + regEx: SimpleSchema.RegEx.id, + }, + }).validator(), + + mixins: [RateLimiterMixin], + rateLimit: { + numRequests: 10, + timeInterval: 5000, + }, + + run({tabletopId, creatureIds}) { + if (!this.userId) { + throw new Meteor.Error('tabletops.addCreatures.denied', + 'You need to be logged in to remove a tabletop'); + } + assertUserHasPaidBenefits(this.userId); + assertUserInTabletop(tabletopId, this.userId); + assertAdmin(this.userId); + + Creatures.update({ + _id: {$in: creatureIds}, + $or: [ + {writers: this.userId}, + {owner: this.userId}, + ], + }, { + $set: {tabletop: tabletopId}, + }, { + multi: true, + }); + }, + +}); + +export default addCreaturesToTabletop; diff --git a/app/imports/api/tabletop/methods/insertTabletop.js b/app/imports/api/tabletop/methods/insertTabletop.js new file mode 100644 index 00000000..0857031a --- /dev/null +++ b/app/imports/api/tabletop/methods/insertTabletop.js @@ -0,0 +1,34 @@ +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; +import Tabletops from '../Tabletops.js'; +import { assertAdmin } from '/imports/api/sharing/sharingPermissions.js'; +import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js'; + +const insertTabletop = new ValidatedMethod({ + + name: 'tabletops.insert', + + validate: null, + + mixins: [RateLimiterMixin], + rateLimit: { + numRequests: 5, + timeInterval: 5000, + }, + + run() { + if (!this.userId) { + throw new Meteor.Error('tabletops.insert.denied', + 'You need to be logged in to insert a tabletop'); + } + assertUserHasPaidBenefits(this.userId); + assertAdmin(this.userId); + + return Tabletops.insert({ + gameMaster: this.userId, + }); + }, + +}); + +export default insertTabletop; diff --git a/app/imports/api/tabletop/methods/removeTabletop.js b/app/imports/api/tabletop/methods/removeTabletop.js new file mode 100644 index 00000000..8341e73b --- /dev/null +++ b/app/imports/api/tabletop/methods/removeTabletop.js @@ -0,0 +1,49 @@ +import SimpleSchema from 'simpl-schema'; +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; +import Tabletops from '../Tabletops.js'; +import { assertAdmin } from '/imports/api/sharing/sharingPermissions.js'; +import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js'; +import { assertUserIsTabletopOwner } from './shared/tabletopPermissions/js'; +import Creatures from '/imports/api/creature/creatures/Creatures.js'; + +const removeTabletop = new ValidatedMethod({ + + name: 'tabletops.remove', + + validate: new SimpleSchema({ + tabletopId: { + type: String, + regEx: SimpleSchema.RegEx.id, + }, + }).validator(), + + mixins: [RateLimiterMixin], + rateLimit: { + numRequests: 5, + timeInterval: 5000, + }, + + run({tabletopId}) { + if (!this.userId) { + throw new Meteor.Error('tabletops.remove.denied', + 'You need to be logged in to remove a tabletop'); + } + assertUserHasPaidBenefits(this.userId); + assertUserIsTabletopOwner(tabletopId, this.userId); + assertAdmin(this.userId); + + let removed = Tabletops.remove({ + _id: tabletopId, + }); + Creatures.update({ + tabletop: tabletopId, + }, { + $unset: {tabletop: 1}, + }); + return removed; + }, + +}); + +export default removeTabletop; diff --git a/app/imports/api/tabletop/methods/shared/tabletopPermissions.js b/app/imports/api/tabletop/methods/shared/tabletopPermissions.js new file mode 100644 index 00000000..2f14543d --- /dev/null +++ b/app/imports/api/tabletop/methods/shared/tabletopPermissions.js @@ -0,0 +1,25 @@ +import Tabletops from '../../Tabletops.js'; + +export function assertUserInTabletop(tabletopId, userId){ + let tabletop = Tabletops.findOne(tabletopId); + if (!tabletop){ + throw new Meteor.Error('Tabletop does not exist', + 'No tabletop could be found for the given tabletop id'); + } + if (tabletop.gameMaster !== userId && !tabletop.players.includes(userId)){ + throw new Meteor.Error('Not in tabletop', + 'The user is not the gamemaster or a player in the given tabletop'); + } +} + +export function assertUserIsTabletopOwner(tabletopId, userId){ + let tabletop = Tabletops.findOne(tabletopId); + if (!tabletop){ + throw new Meteor.Error('Tabletop does not exist', + 'No tabletop could be found for the given tabletop id'); + } + if (tabletop.gameMaster !== userId){ + throw new Meteor.Error('Not the owner', + 'The user is not the owner of the given tabletop'); + } +} diff --git a/app/imports/api/users/Users.js b/app/imports/api/users/Users.js index cd963707..268b8d99 100644 --- a/app/imports/api/users/Users.js +++ b/app/imports/api/users/Users.js @@ -168,12 +168,6 @@ Meteor.users.sendVerificationEmail = new ValidatedMethod({ } }); -Meteor.users.isAdmin = function(userId){ - userId = this.userId || userId; - let user = Meteor.users.findOne(userId); - return user && user.roles.includes('admin'); -} - Meteor.users.canPickUsername = new ValidatedMethod({ name: 'users.canPickUsername', validate: userSchema.pick('username').validator(),