Base solution for your next web application
Open Closed

Suggestion on how to extend Host and Tenant segregation with #5010


User avatar
0
ivanosw1 created

Hi,

We are trying to extend the Tenant separation logic adding Organization units (with Single Deployment - Single Database scenario).

The main idea is that the data's owner can be Host, Tenant or Organization Unit. Host, Tenant and Organization Unit have a hierarchical relationship.

Host has data that can be viewed by every Tenants. Tentant has data that can be viewed by his Organization Units. OrganizationUnit has data that can be viewed only by itself.

Every user belongs to one Host, one Tenant and many Organization Units (but only one at the same time). So, a logged user, has always a Host, a TenantId and a OrganizatinUnitId.

When data are retrived from repository they should be automatic filtered by current Host, current TenantId and current OrganizationUnitId. But there shuold be also a standard way to get entities including parents or children so that every developer does not have to rewrite the search logics In that manner normal user can show in a readonly mode Host's data, Tenant's data and , in write mode, own data. Same logic per Tenant users and Host users.

I guess that a new IMayHaveOrganizationUnit can help but the main point is that all has to be provided by the framework itself.

Do you have some suggestions about ?

Thank you


5 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @ivanosw1,

    As you know ABP Framework and AspNet Zero doesn't contain a filter for Organization Units. So, adding an interface like IMayHaveOrganizationUnit and filtering data accordingly is what you want I guess.

    By the keyword "Host", do you mean "TenantId=null" or a new HostId ?

  • User Avatar
    0
    ivanosw1 created

    Yes, I mean "TenantId=null".

    What I would like to know is what you would do to implement this scenario. Some way that is compliant with AspNetBoilerplat. I don't want loose all the advantages provided by core version, but extend it.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @ ivanosw1,

    Maybe I couldn't understand your case very well, I'm not sure :).

    Every user belongs to one Host, one Tenant and many Organization Units (but only one at the same time). So, a logged user, has always a Host, a TenantId and a OrganizatinUnitId.

    If you mean TenantId=null bu the Host term, then your above scenario seems impossible because for a user TenantId field cannot be "null" and "some int value" at the same time. So, if you are using IMayHaveTenant interface, an entity will have single nullable TenantId field.

    For organization unit filtering we suggest you to apply it with an interface like "IMayHaveOrganizationUnit" and create a dynamic filter for this interface as well.

  • User Avatar
    0
    ivanosw1 created

    I' sorry. Isn't simple our scenario. To be more practical, how can I add a filter to EFCore?

    From docs: ORM Integrations Data filtering for pre-defined filters works for NHibernate, Entity Framework 6.x and Entity Framework Core. Currently, you can only define custom filters for Entity Framework 6.x.

  • User Avatar
    0
    alper created
    Support Team

    Adding your custom data filter in EF Core;

    public class Blog
    {
        private string _tenantId;
    
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
    
        public List<Post> Posts { get; set; }
    }
    
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public bool IsDeleted { get; set; }
    
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");
    
        // Configure entity filters
        modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
        modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
    }
    

    Sample code <a class="postlink" href="https://github.com/aspnet/EntityFrameworkCore/tree/dev/samples/QueryFilters">https://github.com/aspnet/EntityFramewo ... eryFilters</a>

    Docs <a class="postlink" href="https://docs.microsoft.com/en-us/ef/core/querying/filters">https://docs.microsoft.com/en-us/ef/cor ... ng/filters</a>