horizon icon indicating copy to clipboard operation
horizon copied to clipboard

Permissions in client

Open ivan-kleshnin opened this issue 9 years ago • 8 comments

How to check (in browser) if some operation is allowed? Common need: to hide corresponding UI element.

ivan-kleshnin avatar Aug 29 '16 13:08 ivan-kleshnin

There's not a way to do this programmatically, and it's probably mildly less secure than having it. You could do something like:

  1. run a test query
  2. If the query succeeds or fails, write to the hz('users').update({id: userId, allowed_to_X: true})
  3. Use hz.currentUser().watch() to decide whether to show ui widgets.

This would be susceptible to editing by the user, but since it doesn't change their actual permissions it should be fine

deontologician avatar Aug 29 '16 21:08 deontologician

There's not a way to do this programmatically, and it's probably mildly less secure than having it

I don't see how it may be less secure. It should be kinda like HEAD HTTP request which pings backend to see what's there. In our case it should ping to see what's allowed.

Method you describe is not general. We can't check for update permissions if versioning is involved. It's a problem to check for remove permissions. All that needs some testing mini-framework, at least, with predefined "safe" sequences of operations.

ivan-kleshnin avatar Aug 30 '16 07:08 ivan-kleshnin

That sounds like we'll need some kind of dry-run functionality for this.

We can't generally test permissions without sending the query all the way through to the database, because there might be validator functions that rely on the actual contents of the documents that are being read or modified.

With a dry-run flag, we would actually perform all operations, except that writes would be turned into no-ops in the last moment.

danielmewes avatar Aug 30 '16 19:08 danielmewes

@ivan-kleshnin it seems like it would be more robust to structure your permission groups in a way that reflects which portions of the UI should be visible. Then you can simply check if your user is a member of the group required by that element in the hz.currentUser() response.

marshall007 avatar Aug 30 '16 20:08 marshall007

@deontologician we could even expose hz.isMember('<group>') as an Observable<boolean> if this is a common use-case.

marshall007 avatar Aug 30 '16 20:08 marshall007

We really need to figure out a story for dynamic groups. Right now, since they're so tied to permissions, we can't reasonably generate them on the fly, they're kind of like configuration. If we could build dynamic groups and dynamically apply permissions to them (maybe from some predefined pool), it would make it much more reasonable to use group membership to hide/alter elements of the UI.

I do think this is the way to do this kind of thing though

deontologician avatar Aug 30 '16 22:08 deontologician

I opened #801 to discuss dynamic groups. I think I'm leaning against isMember since it's implemented as hz.currentUser().watch().map(u => u.groups.includes(groupName))

deontologician avatar Aug 30 '16 22:08 deontologician

Thanks to all for the answers. I agree that testing for groups membership should be enough for most UI switching cases.

ivan-kleshnin avatar Aug 31 '16 09:08 ivan-kleshnin