Search code examples
databaseservicestackmulti-tenantservicestack-autoqueryautoquery-servicestack

Filtering AutoQuery Results to Only Display Table Rows that Match Data in the Users Session


I'm working on a project that want's to control data access in a multi-tenant system. I've got a table set up which has a row on it that says what tenant the object applies to. Let's call this property

ClientObject.ClientOrgId

I want to set something up so that anytime this table is accessed the only results that are returned are results that match some piece of data in the users session. I.e.

ClientObject.ClientOrgId == UserSession.ClientOrgId

and I ideally want to do this restriction on the table model instead of re-implementing it for every query created.

I've found the Autofilter attribute in the service stack documentation, and it looks like the thing that I want to use, but I've been unable to get it working. An example of my code is below, and I'm not seeing any filtering whenever I set the user sessions ClientOrgID to anything different.

[Authenticate]
[Route("/clientObject", HttpMethods.Post)]
[Api("Creates a Client Object")]
public class CreateClientObject : ICreateDb<ClientObjectTableModel>, IReturn<ClientObjectMutationResponse>
{
    [ValidateNotEmpty]
    public string ClientName{ get; set; }

    [ValidateNotEmpty]
    public string ClientLocation { get; set; }

    [ValidateNotEmpty]
    [ValidateNotNull]
    public Guid? ClientOrgId { get; set; }
}

[AutoFilter(QueryTerm.Ensure, nameof(ClientObjectTableModel.ClientOrgId), Eval= "userSession.ClientOrgId")]
public class ClientObjectTableModel : AuditBase
{
    [AutoId]
    public Guid Id { get; set; }

    [Required]
    public string ClientName { get; set; }

    [Required]
    public string ClientLocation { get; set; }

    [Required]
    public Guid ClientOrgId { get; set; }
}

I even went off the rails and tried something like

[AutoFilter(QueryTerm.Ensure, nameof(ClientObjectTableModel.ClientLocation), Value = "The Fourth Moon Of Mars")]

with the expectation that nothing would get returned, and yet I'm still seeing results.


Solution

  • All AutoQuery CRUD Attribute like [AutoFilter] should be applied to the AutoQuery Request DTO, not the data model.

    Have a look at how to populate Tenant Ids with AutoPopulate and how it's later used to filter results with [AutoFilter].