Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update failed: Access denied. Operator $setOnInsert not allowed in a restricted collection. #146

Open
lehtu opened this issue Jun 8, 2017 · 12 comments

Comments

@lehtu
Copy link

lehtu commented Jun 8, 2017

Hey guys! I'm getting this error while trying to update profile.name on clientside:

update failed: Access denied. Operator $setOnInsert not allowed in a restricted collection.

Here is my profile.name schema (no autoValue or defaultValue!)

  name: {
    type: String,
    label: "Nimi",
    optional: false,
    custom: function () {
      if (!this.value)
        return 'required';
    }
  },

..and here is the demonstration on chrome console
screen shot 2017-06-08 at 11 58 57

@lehtu
Copy link
Author

lehtu commented Jun 8, 2017

Okay, it looks like that if there is even single defaultValue in the whole(not necesseraly in the field you are trying to update) Schema then it does this.

@lehtu
Copy link
Author

lehtu commented Jun 8, 2017

working work around for this was found from here: Meteor-Community-Packages/meteor-autoform#1582 (comment)

const defaultValue = value => function autoValue() {
  if (!this.isUpdate && !this.isUpsert && !this.isSet) {
    return value;
  }
};

// Schema field definition
fieldName: {
  type: Number,
  autoValue: defaultValue(10),
}

It's not optimal, but atleast it works for now..

@lehtu
Copy link
Author

lehtu commented Jun 8, 2017

by the way if you didn't get that already, this is killing latency compensation for good

@hexsprite
Copy link

$setOnInsert is not an allowed update parameter for Meteor in allow-deny Meteor package.

See https://github.com/meteor/meteor/blob/master/packages/allow-deny/allow-deny.js#L354

@aldeed any thoughts on this?

@hexsprite
Copy link

Seems like the proper thing to do would be to modify the Meteor allow-deny package to support $setOnInsert as be included in ALLOWED_UPDATE_OPERATIONS

@hexsprite
Copy link

Just in case anyone runs into this issue I can confirm that simply copying the allow-deny package from Meteor dev and modifying it to allow $setOnInsert is a good workaround. Sometime soon I'll submit a PR to Meteor if they don't fix it first.

@DerekTBrown
Copy link
Contributor

@hexsprite why does node-simple-schema need to use $setOnInsert? Why couldn't node-simple-schema simply replace the underlying logic for defaultValue to the one used here (Meteor-Community-Packages/meteor-autoform#1582 (comment))?

@hexsprite
Copy link

@DerekTBrown yeah good question!

@jdavidberger
Copy link

This approach seems to have a major drawback: If you do it with an empty string, that field now validates only when there is some text -- setting the default to an empty string keeps 'clean' from clearing it out; doesn't do that with autorun.

Set 'optional: true' on the field to fix this; but now you have to sort of deal with undefined, so it isn't ideal.

@aldeed
Copy link
Collaborator

aldeed commented Nov 13, 2017

why does node-simple-schema need to use $setOnInsert

If you are doing an upsert and you have a defaultValue, it assumes you want to set that default if your update ends up being an insert, same as what would happen if you do the insert directly.

The problem is with this comment here: https://github.com/aldeed/node-simple-schema/blob/ae35eafd7e593ff2694632c7004a5c1ebc0c1790/lib/SimpleSchema.js#L837-L838

We assume that Mongo won't mind the $setOnInsert being there, and it's true Mongo does not mind but Meteor DOES mind if you're calling update on the client.

The checks like this.isUpsert, etc. are not part of this package. They're added by collection2 since simple-schema is not database-aware. So the solution would be to either build those into this package (i.e., needing to pass { upsert: true } option to clean function so that it knows) OR have the collection2 package override the default defaultValue function.

@pward123
Copy link

FYI, I've run into a problem that, while not necessarily caused by this, is exacerbating the problem.

When specifying a default value for an array nested inside another array, you'll end up with positional operators in the $setOnInsert. Even when doing an update (without upsert), the cleaned modifier ends up containing something like {"layout.0.zones.$.align": "center"}. This causes mongo to reject the update.

@aldeed
Copy link
Collaborator

aldeed commented Dec 29, 2017

@pward123 Would you mind submitting a separate issue for that, including an example schema and example modifier that results in the issue happening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants