strongloop / strong-remoting

Communicate between objects in servers, mobile apps, and other servers.
www.strongloop.com
Other
105 stars 93 forks source link

Cannot disable PATCH /Model/{id} method #335

Closed gemabarni closed 8 years ago

gemabarni commented 8 years ago

I was trying to disable all remote methods for my model except a few ones, but I found no way to disable PATCH /Model/{id} method. Theoretically it should be disabled by calling Model.sharedClass.disableMethodByName('patchAttributes'), but it still remains in the explorer. However when trying to invoke it, it returns with code 500 - "remoting.context option was removed in version 3.0. See https://docs.strongloop.com/display/APIC/Using%20current%20context for more details." I guess it comes up because unlike other methods, this one is attached to the prototype of my model. (My model's base is the built-in user model.)

richardpringle commented 8 years ago

@gemabarni you should be able to do the following:

var ExtendedUser = app.models.ExtendedUser

ExtendedUser.disableRemoteMethod('updateAttributes') 

You can do this in the boot(...) function callback or in a boot script. Let me know how that goes.

I did find however that I was unable to disable upsert....

Edit: I was missing an argument with disableRemote.('upsert', true). The second argument, "isStatic" must be set to true or else it will default to false and the actual method will not be disabled.

Closing the issue.

gemabarni commented 8 years ago

Thanks for the idea, finally I managed to get rid of all methods of my extended user using the following boot script:

module.exports = function disable(app) {
  var ExtendedUser = app.models.ExtendedUser;
  ExtendedUser.disableRemoteMethod('patchAttributes', false);
  ExtendedUser.disableRemoteMethod('patchOrCreate', true);
  ExtendedUser.disableRemoteMethod('create', true);
  ExtendedUser.disableRemoteMethod('upsert', true);
  ExtendedUser.disableRemoteMethod('exists', true);
  ExtendedUser.disableRemoteMethod('findById', true);
  ExtendedUser.disableRemoteMethod('deleteById', true);
  ExtendedUser.disableRemoteMethod('count', true);
  ExtendedUser.disableRemoteMethod('find', true);
  ExtendedUser.disableRemoteMethod('findOne', true);
  ExtendedUser.disableRemoteMethod('createChangeStream', true);
  ExtendedUser.disableRemoteMethod('updateAll', true);
  ExtendedUser.disableRemoteMethod('replaceById', true);
  ExtendedUser.disableRemoteMethod('replaceOrCreate', true);
}

However I tried to delete the lines one by one and I found that ExtendedUser.disableRemoteMethod('upsert', true); had no effect. After deleting that line the explorer remained empty. Could you explain which method should it represent?

Another thing that I noticed is a deprecated warning when calling the disableRemoteMethod the first time:

strong-remoting deprecated SharedClass.prototype.disableMethod is deprecated. Use SharedClass.prototype.disableMethodByName instead. node_modules\loopback\lib\model.js:443:22

That's why I was trying to use Model.sharedClass.disableMethodByName in the first place. I looked up the source and found that disableRemoteMethod was still calling this deprecated method. Should I post an issue about that in the loopback repository?

richardpringle commented 8 years ago

@gemabarni, that would be great if you could open the issue about disableRemoteMethod in the LoopBack repo!

Also, 'replaceOrCreate' was an alias for 'upsert' in LoopBack 2.x but in 3.x the name has been replaced by the alias, so you can get rid of it in your boot script.

thatbeardo commented 6 years ago

I am facing the same issue right now. I want to disable the PATCH endpoint. It seems that it can only be disabled by using MyModel.disableRemoteMethod('updateAttributes'); Using the function disableRemoteMethod gives me a deprecated warning. @gemabarni, did you post an issue about this? Or did you find a way to solve this problem

mightytyphoon commented 6 years ago

Hi, if you are still struggling with this, I put some times understanding the code (because I don't like warning even if disableRemoteMethod() works)

So here is the solution :

Model.disableRemoteMethodByName('prototype.updateAttributes')

This is because updateAttributes() is bounded to Model.prototype.updateAttributes and not to Model.updateAttributes.

disableRemoteMethodByName will disable methods by their key. So when you do Model.disableRemoteMethodByName('updateAttributes') you actually tell loopback to disable Model['updateAttributes'], which does not exist.

update : Here is the full code to hide all remote method :

  //static methods
  Enseigne.disableRemoteMethodByName('create')
  Enseigne.disableRemoteMethodByName('count')
  Enseigne.disableRemoteMethodByName('patchOrCreate')
  Enseigne.disableRemoteMethodByName('replaceOrCreate')
  Enseigne.disableRemoteMethodByName('findById')
  Enseigne.disableRemoteMethodByName('exists')
  Enseigne.disableRemoteMethodByName('find')
  Enseigne.disableRemoteMethodByName('replaceById')
  Enseigne.disableRemoteMethodByName('findOne')
  Enseigne.disableRemoteMethodByName('deleteById')
  Enseigne.disableRemoteMethodByName('upsertWithWhere')
  Enseigne.disableRemoteMethodByName('updateAll')
  Enseigne.disableRemoteMethodByName('createChangeStream')

  //prototype method
  Enseigne.disableRemoteMethodByName('prototype.updateAttributes')

cheers.

murphylan commented 6 years ago

const remoteMethodNames = ['findById', 'findOne', 'confirm', 'count', 'exists', 'create', 'upsert', 'deleteById', 'updateAll', 'prototype.updateAttributes', 'createChangeStream', 'replaceById', 'replaceOrCreate', 'upsertWithWhere'];

        remoteMethodNames.forEach(function (value) {
            Model.disableRemoteMethodByName(value);
        });