Domanda

I'm using Meteor.methods to upsert, but it's not secure, since trusted code avoids the allow/deny rules. I have these two running on both the client and server:

//update today's topics
Meteor.methods({
  todayUpsert: function(id, doc){
     Today.upsert(id, doc);
  }
});

//update reviews
Meteor.methods({
  reviewUpsert: function(id, doc){
     Reviews.upsert(id, doc);
  }
});

The first one should only be accessible to the admin user. The second one should only be accessible to the document owner.

Can someone help me figure out how to write that? When I had it written in the allow/deny rules without using meteor.call, it looked something like this:

function adminUser(userId) {
    var adminUser = Meteor.users.findOne({username:"Quin"});
    return (userId && adminUser && userId === adminUser._id);
}

Topics.allow({
    insert: function(userId, doc){
        return adminUser(userId);
    },
    update: function(userId, doc, fields, modifier){
        return adminUser(userId);
    },
    remove: function(userId, doc){
        return adminUser(userId);
    },
    fetch: ['user']
});

Reviews.allow({
  insert: function (userId, doc) {
    // the user must be logged in, and the document must be owned by the user
    return (userId && doc.user === userId && Meteor.user().emails[0].verified === true);
  },
  update: function (userId, doc, modifier) {
    // can only change your own documents
    return (doc.user === userId && Meteor.user().emails[0].verified === true);
  },
  remove: function (userId, doc) {
    // can only remove your own documents
    return doc.user === userId;
  },
  fetch: ['user']
});
È stato utile?

Soluzione

Inside methods, this.userId is the user ID of the user who called the method (or null if they aren't logged in). You can check that, and throw a Meteor.Error if it's not the admin account.

//update today's topics
Meteor.methods({
  todayUpsert: function(id, doc) {
    if (!adminUser(this.userId)) {
      throw new Meteor.Error(403, "You must be an admin to do that");
    }
    Today.upsert(id, doc);
  }
});

//update reviews
Meteor.methods({
  reviewUpsert: function(id, doc) {
    if (!this.userId) {
      throw new Meteor.Error(403, "You must be logged in to do that");
    }
    if (Meteor.users.findOne(this.userId).emails[0].verified !== true) {
      throw new Meteor.Error(403, "Your email must be verified to do that")
    }

    var review = Reviews.findOne(id);
    if (review && review.owner !== this.userId) {
      throw new Meteor.Error(403, "You don't own that review");
    }
    if (doc.owner !== this.userId) {
      throw new Meteor.Error(403, "Cannot create a review for someone else");
      // alternatively, just set doc.owner = this.userId
    }

    Reviews.upsert(id, doc);
  }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top