Meteor-Community-Packages / meteor-roles

Authorization package for Meteor, compatible with built-in accounts packages
http://meteor-community-packages.github.io/meteor-roles/
MIT License
920 stars 167 forks source link

Approach for subdivision within multi-tenant app #314

Open Ajaay opened 4 years ago

Ajaay commented 4 years ago

Hi,

I need to support multiple tenants (different companies), which are further subdivided by teams that should not be able to see each other's data. An example structure below:

Company 1 Company 2 Company 3
Team 1 Team 2 Team 1 Team 1 Team 2
User 1 User 4 User 6 User 9
User 2 User 5 User 7 User 10
User 3 User 8

Within each of those teams I then want to be able to assign permissions to each user.

There should be a team owner that's effectively the admin for that team. And a super user at each company level that has control over their teams.

Is this possible solely through meteor-roles?

It looks like scopes might be suitable but I think you'd need the ability to define multiple scopes - one for the company and another for the team.

Any ideas on how to achieve this would be hugely appreciated 👍

Thanks!

SimonSimCity commented 4 years ago

Depending on how you set it up it might require some twist in mind.

E.g. I write a software for managing projects.

Each project might assigned to a team and/or an individual person. A person now also has a team assigned.

Now assigning a user of the team Team1 the global role team-admin will give him access to all the projects which are assigned to this team. I can also give him access to an individual project by assigning him a role by the scope project/${id}. I do this by simply extending the function Roles.userIsInRole().

Depending on what you want a user to give access to, this same approach might work - but can also make it very hard. E.g. having a person in multiple teams will now again make it harder - having projects assigned to multiple teams as well.

Please also take a read on this where I discuss some ideas with the former lead developer: https://github.com/Meteor-Community-Packages/meteor-roles/issues/270

You ask me if this is possible - well, this always depends on your use-case. This use-case just describes that you have a hierarchy - but not who should have access to what and when. So, I can't answer you to this question before providing me additional information about the relation of role assignments.

Ajaay commented 4 years ago

Thanks for the detailed response.

If we take your example then, in my case projects would only ever be assigned to one team, and as an initial release I think having users belonging to one team would be fine as well. The exception being the global admins or account-owner as I call them, who should have access to all documents within their Company account.

The team-admin should see all projects in their team and have full read/write permissions. They should be able to assign users permissions within their team giving access to all or select projects for a given user.

At the moment my Company1, Company2, Company3 requirement is handled by adding an org field to all documents including the user document, so that I can reference it in any methods/publications.

The teams capability is a new requirement that I think could be achieved using scopes. Or just by mimicking what I have already for org by adding one further team field.

Does that help narrow down the requirement somewhat?

Thanks for your help!

SimonSimCity commented 4 years ago

So ... why not do it as I did with the account-owners as an additional layer to team?

It is a twist in mind, as I said, which makes it possible.

Every time I ask for a permission, I ask so as of the scope of a particular project. If now my function Roles.userIsInRole() receives a scope, which matches ^project\/(.+)$, I fetch this related project and if the user has the same team as the project, I also check for the role of the scope team. You could match this against the team of the user and against the company. This might also work for users being part of multiple scopes ...

But to be honest, an option for querying for an array of scopes, where it would match if either of those are given, could maybe help here. It might require some performance testing though.

If you have the time, I'd assist you to create a PR for it if you rather want to go down this line. But this wouldn't be much different than running it with the option of a scope multiple times, I guess. I'll leave this up to you.