Finbuckle / Finbuckle.MultiTenant

Finbuckle.MultiTenant is an open-source multitenancy middleware library for .NET. It enables tenant resolution, per-tenant app behavior, and per-tenant data isolation.
https://www.finbuckle.com/multitenant
Apache License 2.0
1.26k stars 256 forks source link

Question: Multitenant within Multitenant? #421

Open hbermani opened 3 years ago

hbermani commented 3 years ago

So here is an interesting scenario.

You have 6 tenants, each with their own tenant-id. Three tenants decide they want to collaborate and want their data connected whilst still respecting data sovereignty. My immediate thinking is that the three tenants will need to share the same tenant-id and then segregation would be done through business logic so EF just talks to one tenant instance. But what would be really nice is the ability to maintain each tenant's tenant-id, perhaps keep them in the same Db, and get EF Core to query across the whole Db (Perhaps get the library to recognise multi-level tenant identifier (e.g. projectAlpha-tenant1 , projectAlpha-tenant2... and have the option to selectively query filter by projectAlpha)

Would welcome your thoughts as to how best to achieve such scenario with this amazing library.

AndrewTriesToCode commented 3 years ago

Hi @hbermani Sorry for the late reply -- I think what you described is a good approach. Nothing in the library specifically addresses this type of need. I think it also depends on what the tenant specific requirements are -- separate users? data? authentication? etc. And for the "sibling" tenants what information would they be sharing as common between them?

If you treat the "supertenant" as the Finbuckle tenant then you effectively treat all the subtenants the same and would haev to do your own separation within -- kinda defeats teh point of Finbuckle.MultiTenant but at least it helps at the super level.

hbermani commented 3 years ago

Hi @AndrewTriesToCode , Thank you for your input, honestly no need to apologise, it must be challenging keeping this ticking.

So here is my current thinking.

The simplified version:

The over engineered version:

Get Scenario:

  1. Authentication can be managed externally,
  2. bearer token claims gets passed into custom Multitenant strategy, getIdentifierAsync return tenant-id (projectAlpha-tenant2) .
  3. The request reaches a controller action that is dedicated to a shared resource (e.g. A controller that returns a list of shared forms/documents/projects). The controller will amend the tenant id in the DI injected db context to (projectAlpha) (Perhaps expose a helper method to do that, unless it's as simple as changing a value on the fly)
  4. EF would generate the query and append query filter "tenant-id CONTAINS / SQL Like projectAlpha" instead of what I expect the library does now (==), this is an internal library workings.

Post Scenario (Gets a bit complicated, E.g. a shared form with tasks users across multiple tenants in the same Db):

  1. Authentication can be managed externally,
  2. bearer token claims gets passed into custom Multitenant strategy, getIdentifierAsync return tenant-id (projectAlpha-tenant2) .
  3. The request reaches a controller action that is dedicated to a shared resource (e.g. A controller that stores a shared form/document/project and associated tasks users). The controller will need to generate queries like the following:
    • Store a record with tenant-id (projectAlpha-tenant2), this will have a bool property to say it's a shared record.
      • Then SaveChangeAsync()
    • Now amend the context tenant-id to 'projectAlpha' to retrieve task users from siblings with query filter "tenant-id CONTAINS / SQL Like projectAlpha"
    • For each task user for that record
      • Use the existing task users tenant-id and store by calling SaveChangesAsync()

How easy would it be to enable a 'Contains'/'Like' tenant-id comparator to be triggered after a MultitenantDbContext has been instantiated / when it's created as a shared context in the simplified version, as that seems to be the key to enable this functionality?

Thank you

AndrewTriesToCode commented 3 years ago

I keep coming across more and more use cases where a "tenant group" or similar would be useful to have. Did you make any progress on this in your use case?

hbermani commented 3 years ago

Hi Andrew,

Unfortunately, I haven't, the project priorities changed and I haven't had a chance to progress this yet.