Hi - I am creating an app where a User can be a member of one or more teams. I want a privacy rule which allows a User to see information about all the other Users whom they’re in a team with.
If each User could only be in one team, I’d simply say “If this User’s Team is Current User’s Team” then make data visible.
But there seems to be no way to say “If this User’s Teams [includes one of] Current User’s Teams”. - i.e. the Many-to-Many relationship between Users and Teams makes it complicated.
Did anyone find a pragmatic solution to deal with this? It seems like it should be a common issue.
I don’t have any good solution to this. There are very few operators available for testing values in Privacy Rules (contains, is empty … basically) so any hack you dream up like regex matching a string is not going to work.
When faced with this, I’ve changed the App design to have a concept of “active team” - so when a User wants to see a Teams data - they have to have changed their “active team” to be the team they want to view the data of. (eg like an explicit choice on login) then Privacy Rules can work in the usual fashion.
Maybe some bright spark will have a better suggestion
This is my approach as well, however, how do you contend with different sets of permissions between those Teams if a user can only have one security group? Basically if you change the active Team they might be able to see things they shouldn’t be able to.
One way to solve this is to create another table to store the association between the user and the team/company but also have a security group and apply your same logic to the “current team” and set a “current security group.
A ‘Permission’ or ‘Role’ data type which stores permissions data for a particular User and particular Team.
For some of my apps where users are part of multiple times, we store a List of Permissions on the User (as well as List of Teams). When the user updates their Selected Team, we updated their Selected Permissions too. Workflow/element conditions reference Current User’s Selected Permissions (the permission the user has within the team)
For ManyToMany relationship, you can create a new DataType called “Team Member” which will have 2 fields a Team and a User. And when you want to give access to User of a team, you can create a new record of TeamMember table. And you can revoke access by deleting the TeamMember record.
In privacy rules, you can check if TeamMember object exists with the User and the Team or not, if exists, then grant access.
Are the different permissions stored as Option Sets which are then added to a related field on the User?
Depends on the app, sometimes the Permission data type has a field for each permission, other times it will have a List of Permissions where permission is an option set that grants permission to do something. The reason for the former is when the admin needs to be able to customise limits (e.g can create precisely 10 projects)
Isn’t that a bad practice for security as all permissions are accessible and therefore a bad actor can know how to alter there permissions field to gain access to things they otherwise shouldn’t have access to?
You can’t just modify any field you want to Bubble.
Fields are modified by autobinding, by data API, or by workflows
If autobinding, sure, they can edit them.
If using a workflow, then conditions on the workflows will protect them.
API calls, if the app has them exposed for User data type, which I think most might if they use SSO?
I’ve successfully used exactly the approach cited by @lindsay_knowcode and @georgecollier. FYI, @marketing15, here’s a rough outline to illustrate one implementation that accounts for roles with different constellations of permissions as well as disabling a user’s membership at the team level. As we’re all accustomed to in Bubble, it includes various fields that facilitate privacy rule expressions but otherwise wouldn’t be needed in a fully normalized database.
Data Type | Fields |
---|---|
User | * Related Teams * Related Memberships * Selected Membership |
Team | * Enabled Users * Enabled Memberships |
Membership | * Team * User * Role * Enabled (yes/no) |
Role | * Label (text) * Permission 1 (yes/no) * Permission 2 (yes/no) * Permission 3 (yes/no) * Permission x (yes/no) |
Thanks, all, for your replies.
So @davidb , if I take your data structure above, what would the privacy rule look like which enables the Current User to see the data of a User in one of their teams?
Would I write: “If Current User’s Selected Membership’s Team includes This User”?
Using the data schema I outlined, your example rule would be the following, which you could try but might comprise too many nested levels:
Current User's Selected Membership's Team's Enabled Users contains This User
Following is how I have implemented the particular point you’re asking about:
This User's Related Teams contains Current User's Selected Membership's Team
Here’s a fuller example accounting for the current user’s status:
Current User's Selected Membership's Enabled is yes and Current User's Selected Membership's Role's Permission 1 is yes and This User's Related Teams contains Current User's Selected Membership's Team
Thank you!