dimanche 19 avril 2015

Does modelObject.save() only update an existing database document when the modelObject was obtained from the database itself?

To use an example that demonstrates the question, assume I have a User model defined by the following schema:



var UserSchema = new Schema({
username: String,
email: String
}
mongoose.model('User', UserSchema);


I know that to update a user using the save method, I could query the user and then save changes like so:



User.findOne({username: usernameTofind}, function(err, user) {
//ignore errors for brevity
user.email = newEmail;
user.save(function(err) { console.log('User email updated') });
});


But if I try to create a new User object with the exact same field values (including the _id) is there any possibility of overwriting the database document? I would assume not, because in theory this would mean that a malicious user could exploit an insecure api and overwrite existing documents (for instance using a 'Create a New Account' request, which wouldn't/couldn't rely on the user already being authenticated) , but more importantly, when I try to do this using a request tool (I'm using Postman, but I'm sure a similar curl command would suffice), I get a duplicate _id error



MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index


So I just want to clarify that the only way to update an existing document is to query for the document, modify the returned instance, then call the save method on that instance, OR use the static update(). Both of these could be secured by requiring authentication.


If it helps, my motivation for this question is mentioned above, in that I want to make sure a user is not able to overwrite an existing document if a method such as the following is exposed publicly:



userCtrl.create = function(req, res, next) {
var user = new User(req.body);

user.save(function(err) {
if (err) {
return next(err);
} else {
res.json(user);
}
});
};


Quick Edit: I just realized, if this is the case, then how does the database know the difference between the queried instance and a new User object with the exact same keys and properties?


Aucun commentaire:

Enregistrer un commentaire