Skip to content

Commit

Permalink
collection.update() and .remove() may only use IDs as selectors when …
Browse files Browse the repository at this point in the history
…sending RPCs.

ie, they can use arbitrary selectors on the server and in client stubs, but not
in other client contexts. This is to prevent clients from executing arbitrary
selectors against the DB.

Because of this, the update and remove allow/deny callbacks can only ever get
one doc, so switch them from getting an array to just getting the doc (like
insert).
  • Loading branch information
glasser committed Mar 13, 2013
1 parent 2d8b41a commit 95edb83
Show file tree
Hide file tree
Showing 6 changed files with 490 additions and 479 deletions.
34 changes: 15 additions & 19 deletions examples/parties/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,22 @@ Parties.allow({
insert: function (userId, party) {
return false; // no cowboy inserts -- use createParty method
},
update: function (userId, parties, fields, modifier) {
return _.all(parties, function (party) {
if (userId !== party.owner)
return false; // not the owner

var allowed = ["title", "description", "x", "y"];
if (_.difference(fields, allowed).length)
return false; // tried to write to forbidden field

// A good improvement would be to validate the type of the new
// value of the field (and if a string, the length.) In the
// future Meteor will have a schema system to makes that easier.
return true;
});
update: function (userId, party, fields, modifier) {
if (userId !== party.owner)
return false; // not the owner

var allowed = ["title", "description", "x", "y"];
if (_.difference(fields, allowed).length)
return false; // tried to write to forbidden field

// A good improvement would be to validate the type of the new
// value of the field (and if a string, the length.) In the
// future Meteor will have a schema system to makes that easier.
return true;
},
remove: function (userId, parties) {
return ! _.any(parties, function (party) {
// deny if not the owner, or if other people are going
return party.owner !== userId || attending(party) > 0;
});
remove: function (userId, party) {
// You can only remove parties that you created and nobody is going to.
return party.owner === userId && attending(party) === 0;
}
});

Expand Down
8 changes: 8 additions & 0 deletions packages/minimongo/objectid.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ LocalCollection._selectorIsId = function (selector) {
selector instanceof LocalCollection._ObjectID;
};

// Is the selector just lookup by _id (shorthand or not)?
LocalCollection._selectorIsIdPerhapsAsObject = function (selector) {
return LocalCollection._selectorIsId(selector) ||
(selector && typeof selector === "object" &&
selector._id && LocalCollection._selectorIsId(selector._id) &&
_.size(selector) === 1);
};

// If this is a selector which explicitly constrains the match by ID to a finite
// number of documents, returns a list of their IDs. Otherwise returns
// null. Note that the selector may have other restrictions so it may not even
Expand Down
Loading

0 comments on commit 95edb83

Please sign in to comment.