Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect properties for different roles using loopback

I was just wondering how you would restrict property access to the $owner role only. For instance in my case I have a Joke which has an Author. The Author has User as base. I would like other "Authers" / Users to see who created the Joke, but they should not be able to see the Authers email, only if the Author is the $owner of the Joke itself it should be OK to show their email, just for the sake of this case.

Looking at the built-in User model you can see that they use the hidden feature to hide the password, but using that for their email will also hide their email for the $owner, which is not what I wanted

Let me know if something is not clear.

Thanks in advance

like image 886
chrs Avatar asked Oct 31 '22 11:10

chrs


2 Answers

Register beforeRemote hook and check if current user is the $owner.

Joke.boforeRemote('findById', function(context, joke, next) {
  // 1. find current user by id, using context.req.accessToken.userId
  // 2. check if he is owner or not, by Role.isOwner
  // 3. remove email from returned joke instance if user is not $owner
})

Note: it can be a bit complicated to cover all endpoints that return Jokes. But is there another way to do it?

like image 189
IvanZh Avatar answered Nov 15 '22 06:11

IvanZh


To modify the output/results, you can use the afterRemote hook, as per the docs. The output/results are stored in ctx.result.

'findById' hooks into your GET requests when the call is like GET http://myModel/id. Use 'find' if you are not including the id in your request e.g. GET http://myModel. Just notice that in case of 'find', the returned instance(s) (joke(s)) is usually not just one so it is in an array of objects.

Joke.afterRemote('findById', function(ctx, joke, next) {
  //your code
});
  1. Get the id of current logged-in user: var currentUser = context.req.accessToken.userId
  2. Compare the user id of the current logged-in user with that of the joke owner. If both are not the same (i.e. if (!(currentUser == joke.userId))), then:
  3. before calling next(), remove the email attribute from returned joke instance. Because sometimes some ways don't work, here are a few:

    • delete ctx.result.email;
    • ctx.result.email = '';
    • loop through the attributes and transferring them to a new var, except the email, then save that new var the result: ctx.result = newVar;
like image 31
Shady Anwar Avatar answered Nov 15 '22 06:11

Shady Anwar