diff --git a/apps/meteor/packages/meteor-run-as-user/lib/collection.overwrites.js b/apps/meteor/packages/meteor-run-as-user/lib/collection.overwrites.js index 45eaa8dd5bb70..d93178883b813 100644 --- a/apps/meteor/packages/meteor-run-as-user/lib/collection.overwrites.js +++ b/apps/meteor/packages/meteor-run-as-user/lib/collection.overwrites.js @@ -1,83 +1,36 @@ // TODO: Remove this after meteor fixes the issue // This override fixes a recent issue introduced after the update to Meteor 3.0 // MinimongoCollection.remove(query) where `query` has `_id: { $in: Array }` removes only the first found record. -LocalCollection.prototype['_eachPossiblyMatchingDocAsync'] = async function (selector, fn) { - const specificIds = LocalCollection._idsMatchedBySelector(selector); +LocalCollection.prototype['_eachPossiblyMatchingDocAsync'] = async function (selector, fn) { + const specificIds = LocalCollection._idsMatchedBySelector(selector); - if (specificIds) { - for (const id of specificIds) { - const doc = this._docs.get(id); + if (specificIds) { + for (const id of specificIds) { + const doc = this._docs.get(id); - if (doc && (await fn(doc, id)) === false) { // Changed from `!fn(doc,id)` - break - } - } - } else { - await this._docs.forEachAsync(fn); - } - } - - LocalCollection.prototype['_eachPossiblyMatchingDocSync'] = function (selector, fn) { - const specificIds = LocalCollection._idsMatchedBySelector(selector); - - if (specificIds) { - for (const id of specificIds) { - const doc = this._docs.get(id); - - if (doc && fn(doc, id) === false) { // Changed from `!fn(doc,id)` - break - } - } - } else { - this._docs.forEach(fn); - } - } - -// This file overwrites the default metoer Mongo.Collection modifiers: "insert", -// "update", "remove" -// -// The new methods are checking if Meteor is in "restricted" mode to apply -// allow and deny rules if needed. -// -// This will allow us to run the modifiers inside of a "Meteor.runAsUser" with -// security checks. -_.each(['insert', 'update', 'remove'], function (method) { - var _super = Mongo.Collection.prototype[method]; - - Mongo.Collection.prototype[method] = function (/* arguments */) { - var self = this; - var args = _.toArray(arguments); - - // Check if this method is run in restricted mode and collection is - // restricted. - if (Meteor.isRestricted() && self._restricted) { - var generatedId = null; - if (method === 'insert' && !_.has(args[0], '_id')) { - generatedId = self._makeNewID(); - } - - // short circuit if there is no way it will pass. - if (self._validators[method].allow.length === 0) { - throw new Meteor.Error(403, 'Access denied. No allow validators set on restricted ' + "collection for method '" + method + "'."); + if (doc && (await fn(doc, id)) === false) { + // Changed from `!fn(doc,id)` + break; } + } + } else { + await this._docs.forEachAsync(fn); + } +}; - var validatedMethodName = '_validated' + method.charAt(0).toUpperCase() + method.slice(1); - args.unshift(Meteor.userId()); +LocalCollection.prototype['_eachPossiblyMatchingDocSync'] = function (selector, fn) { + const specificIds = LocalCollection._idsMatchedBySelector(selector); - if (method === 'insert') { - args.push(generatedId); + if (specificIds) { + for (const id of specificIds) { + const doc = this._docs.get(id); - self[validatedMethodName].apply(self, args); - // xxx: for now we return the id since self._validatedInsert doesn't - // yet return the new id - return generatedId || args[0]._id; + if (doc && fn(doc, id) === false) { + // Changed from `!fn(doc,id)` + break; } - - return self[validatedMethodName].apply(self, args); } - - return _super.apply(self, args); - }; -}); - - + } else { + this._docs.forEach(fn); + } +}; diff --git a/apps/meteor/packages/meteor-run-as-user/lib/common.js b/apps/meteor/packages/meteor-run-as-user/lib/common.js index af64b619375fd..9582f55fbd640 100644 --- a/apps/meteor/packages/meteor-run-as-user/lib/common.js +++ b/apps/meteor/packages/meteor-run-as-user/lib/common.js @@ -1,46 +1,3 @@ -// This file adds the actual "Meteor.runAsUser" and "Meteor.isRestricted" api -// -// It's done by using a DDP method invocation, setting a user id and a -// "isRestricted" flag on it. -// -// If run inside of an existing DDP invocation a nested version will be created. - -var restrictedMode = new Meteor.EnvironmentVariable(); - -/** - * Returns true if inside a runAsUser user scope - * @return {Boolean} True if in a runAsUser user scope - */ -Meteor.isRestricted = function () { - return !!restrictedMode.get(); -}; - -/** - * Run code restricted - * @param {Function} f Code to run in restricted mode - * @return {Any} Result of code running - */ -Meteor.runRestricted = function (f) { - if (Meteor.isRestricted()) { - return f(); - } else { - return restrictedMode.withValue(true, f); - } -}; - -/** - * Run code unrestricted - * @param {Function} f Code to run in restricted mode - * @return {Any} Result of code running - */ -Meteor.runUnrestricted = function (f) { - if (Meteor.isRestricted()) { - return restrictedMode.withValue(false, f); - } else { - f(); - } -}; - /** * Run as a user * @param {String} userId The id of user to run as @@ -56,7 +13,7 @@ Meteor.runAsUser = function (userId, f) { ? currentInvocation : { connection: null, - }, + }, ); // Now run as user on this invocation @@ -66,46 +23,3 @@ Meteor.runAsUser = function (userId, f) { return f.apply(invocation, [userId]); }); }; - -/** - * Run as restricted user - * @param {Function} f Function to run unrestricted - * @return {Any} Returns function result - */ -Meteor.runAsRestrictedUser = function (userId, f) { - return Meteor.runRestricted(function () { - return Meteor.runAsUser(userId, f); - }); -}; - -var adminMode = new Meteor.EnvironmentVariable(); - -/** - * Check if code is running isside an invocation / method - */ -Meteor.isAdmin = function () { - return !!adminMode.get(); -}; - -/** - * Make the function run outside invocation - */ -Meteor.runAsAdmin = function (f) { - if (Meteor.isAdmin()) { - return f(); - } else { - return adminMode.withValue(false, f); - } -}; - -/** - * Make sure code runs outside an invocation on the - * server - */ -Meteor.runOutsideInvocation = function (f) { - if (Meteor.isServer && DDP._CurrentInvocation.get()) { - DDP._CurrentInvocation.withValue(null, f); - } else { - f(); - } -}; diff --git a/apps/meteor/packages/meteor-run-as-user/lib/pre.1.0.3.js b/apps/meteor/packages/meteor-run-as-user/lib/pre.1.0.3.js deleted file mode 100644 index 2562011c00da0..0000000000000 --- a/apps/meteor/packages/meteor-run-as-user/lib/pre.1.0.3.js +++ /dev/null @@ -1,94 +0,0 @@ -// This code will go away in later versions of Meteor, this is just a "polyfill" -// until the next release of Meteor maybe 1.0.3? -// -if (typeof DDPCommon === 'undefined') { - DDPCommon = {}; - - DDPCommon.MethodInvocation = function (options) { - var self = this; - - // true if we're running not the actual method, but a stub (that is, - // if we're on a client (which may be a browser, or in the future a - // server connecting to another server) and presently running a - // simulation of a server-side method for latency compensation - // purposes). not currently true except in a client such as a browser, - // since there's usually no point in running stubs unless you have a - // zero-latency connection to the user. - - /** - * @summary Access inside a method invocation. Boolean value, true if this invocation is a stub. - * @locus Anywhere - * @name isSimulation - * @memberOf MethodInvocation - * @instance - * @type {Boolean} - */ - this.isSimulation = options.isSimulation; - - // call this function to allow other method invocations (from the - // same client) to continue running without waiting for this one to - // complete. - this._unblock = options.unblock || function () {}; - this._calledUnblock = false; - - // current user id - - /** - * @summary The id of the user that made this method call, or `null` if no user was logged in. - * @locus Anywhere - * @name userId - * @memberOf MethodInvocation - * @instance - */ - this.userId = options.userId; - - // sets current user id in all appropriate server contexts and - // reruns subscriptions - this._setUserId = options.setUserId || function () {}; - - // On the server, the connection this method call came in on. - - /** - * @summary Access inside a method invocation. The [connection](#meteor_onconnection) that this method was received on. `null` if the method is not associated with a connection, eg. a server initiated method call. - * @locus Server - * @name connection - * @memberOf MethodInvocation - * @instance - */ - this.connection = options.connection; - - // The seed for randomStream value generation - this.randomSeed = options.randomSeed; - - // This is set by RandomStream.get; and holds the random stream state - this.randomStream = null; - }; - - _.extend(DDPCommon.MethodInvocation.prototype, { - /** - * @summary Call inside a method invocation. Allow subsequent method from this client to begin running in a new fiber. - * @locus Server - * @memberOf MethodInvocation - * @instance - */ - unblock: function () { - var self = this; - self._calledUnblock = true; - self._unblock(); - }, - - /** - * @summary Set the logged in user. - * @locus Server - * @memberOf MethodInvocation - * @instance - * @param {String | null} userId The value that should be returned by `userId` on this connection. - */ - setUserId: function (userId) { - var self = this; - if (self._calledUnblock) throw new Error("Can't call setUserId in a method after calling unblock"); - self.userId = userId; - // self._setUserId(userId); - }, - }); -} diff --git a/apps/meteor/packages/meteor-run-as-user/package.js b/apps/meteor/packages/meteor-run-as-user/package.js index 9550ce3d68570..d14ead7a96861 100644 --- a/apps/meteor/packages/meteor-run-as-user/package.js +++ b/apps/meteor/packages/meteor-run-as-user/package.js @@ -7,7 +7,6 @@ Package.describe({ }); Package.onUse(function (api) { - api.use([ 'meteor', 'check', @@ -19,12 +18,5 @@ Package.onUse(function (api) { // 'ddp-client' ]); - api.addFiles( - [ - 'lib/pre.1.0.3.js', // Waiting for ddp-common and ddp-client - 'lib/common.js', - 'lib/collection.overwrites.js', - ], - ['client', 'server'], - ); + api.addFiles(['lib/common.js', 'lib/collection.overwrites.js'], ['client', 'server']); });