Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User access in multiple tenants #91

Closed
cwbrandsdal opened this issue Sep 4, 2023 · 4 comments
Closed

User access in multiple tenants #91

cwbrandsdal opened this issue Sep 4, 2023 · 4 comments

Comments

@cwbrandsdal
Copy link

Is there a way to give a user access to multiple tenants in different parts of the structure? Example a user needs access to south and west, but not north and east. I guess this is hard because that would cause the user to need multiple DataAccess entries and also multiple DataKey?

@JonPSmith
Copy link
Owner

Hi @cwbrandsdal,

Louis Miles asked a similar question to your requirements and you can read my reply here.

If you are creating a multi-tenant using the AuthP library, then you add some extra code to use a "multiple tenants" key instead of the single DataKey that AuthP uses. Here are the extra steps you need to do:

  1. Create a claim using the RegisterAddClaimToUser method which creates the "multiple tenants" key when the user logs in.
  2. To inject this "multiple tenants" key you need to create a new interface / class similar to the AuthP's IGetDataKeyFromUser interface, but provides your "multiple tenants" key.
  3. Register your "multiple tenants" interface / class to the DI in your Program / startup code.
  4. Your tenant DbContext constructor you will put in your "multiple tenants" key interface instead of the AuthP's IGetDataKeyFromUser
  5. In the tenant DbContext's OnModelCreating method you will add the ...HasQueryFilter(p => UserKey.Contains(p.GroupKey); to each tenant entity class.

NOTE: If you need the Admin access tenant data, then you have to do some more work. You can add code to make it work, but its a bit complex so I wouldn't add this unless your really need it.

@JonPSmith
Copy link
Owner

PS. You also need to build some new admin code to create a many-to-many link between the AuthUser and the Tenant entity classes used by AuthP. That shouldn't be too complex.

@cwbrandsdal
Copy link
Author

Thank you so much! I was thinking something like this myself. The only thing that makes this a bit hard to work with is that with the new HasQueryFilter using Contains it really needs to have every single child. Do you know if there is a way to use the StartsWith on multiple values? It seems not to work from my testing because the DataKey/DataKeys are not populated before the HasQueryFilter is set up. I guess this makes it really hard. Do you have any suggestions on how I could do this? All help is appreciated. Thank you so much for a GREAT package! :-)

@JonPSmith
Copy link
Owner

I'm not sure I fully understand your question, but one part stood out:

... the DataKey/DataKeys are not populated before the HasQueryFilter is set up.

The limitation of this approach is a user with many keys, e.g. south and west, cannot create a new entry because you need a single key (e.g. south) to set the DataKey on the entity classes in the tenant database. I was assumed the data was read, but looks at sounds you want read AND write which adds complications. Here are a two approaches:

  1. Have an admin user for each group, e.g. SouthAdmin user, with a single GroupKey, e.g. south, who's job is to add more data. Simple to implement but only good for a multi-tenant where normal users only need to read the data. Only change from the "five steps" described above is you must stop users with multiple GroupKeys from adding data.
  2. When a user wants to add new data, then a dropdown list of the GroupKeys that the user has is shown and the user has to select the correct GroupKey from the dropdown before they can create a new entry. More complex than the first approach, but makes any user to add new data. This adds a extra step to the "five steps" by adding the selected dropdown GroupKey into a "CreateKey" properly in the tenant DbContext, and when new data is written to the database the DataKey on every new entity class is set to the value in the "CreateKey" properly.

NOTE: I didn't explain how the DataKey is set in the "five steps" - see this section in one of my articles.

I hope I have answered your question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants