horizon
horizon copied to clipboard
Permissions in client
How to check (in browser) if some operation is allowed? Common need: to hide corresponding UI element.
There's not a way to do this programmatically, and it's probably mildly less secure than having it. You could do something like:
- run a test query
- If the query succeeds or fails, write to the
hz('users').update({id: userId, allowed_to_X: true}) - 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
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.
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.
@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.
@deontologician we could even expose hz.isMember('<group>') as an Observable<boolean> if this is a common use-case.
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
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))
Thanks to all for the answers. I agree that testing for groups membership should be enough for most UI switching cases.