Query `include` doesn't trigger `beforeFind` trigger for included objects

Hello,

When I was testing parse server I’ve found that, beforeFind trigger is not triggered for included objects in find or get queries using include option.

Is this working as expected?

We’re applying custom ACLs in beforeFInd trigger. Without beforeFind triggers for included objects we’re not able to apply ACLs on included objects.

If this is intentional, could you please help me with alternative solution?

Could you please give an example and/or share some code?

Thanks for the reply. Here’s an example

Client Side code:

const company = new Parse.Object('Company');
company.id = 'company_id';

const query = new Parse.Query('Employee');
query.equalTo('company', company);
query.include('user'); // user is an instance of _User
const results = await query.find()

Cloud Code

Parse.beforeFind('_User', (req) => {
  // This is triggered for Employee class but not for _User class, when above query is executed
  
  // custom acl code using casbin library. Parse ACL is set to public read/write on all classes
})

Please let me know if more information is needed.

I’ve just checked the code and unfortunately beforeFind trigger when not fire in this case for the include query. Basically the trigger is called one layer over (parse-server/rest.js at 9ea355b4635226ae4da17c8cc5fb0321e3fdec5e · parse-community/parse-server · GitHub) the one that is internally used to run the query to include the sub objects (parse-server/RestQuery.js at master · parse-community/parse-server · GitHub). An workaround could be handling this on beforeFind or afterFind trigger of the Employee class.

@hariprasadiit Im curious about your use of casbin for ACL, what are the benefits of using it over the native backed in parse ACL/Role system ?

it’s more flexible. I can implement both ABAC and RBAC using Casbin in one place and it’s portable to other environments.

Main reason is to support multi tenancy, which is a bit complex with Parse ACL/Role system

This is exactly what Im trying to build at the moment, multi tenant SaaS solution. Could I pick your brain on how you are implementing this ?

You can enforce select and exclude for the first class. You can also perform mutations in afterFind.

Parse.Cloud.beforeFind('Employee', async ({query, user}) => {
  query.exclude("user")
// or

  const user = query._where?.user;
  // do custom logic here
});

Thanks for the suggestion. I thought of doing the same.

As per the design should include trigger cloud code trigger or it shouldn’t? isn’t include synonymous to fetching that from client side?

It’ll be a lengthy discussion if I were to mention implementation details here. Could you please be specific on where you need help here? Casbin model and policies?

Just how it works along side Parse. My desired architecture would be separate users by domain/org and under each org have a set of roles which are identical but at least are separated on a domain by domain basis.

Right now im using parse ACL but its restrictive for multi tenant setups

btw I think .include() is used when you have a pointer on an object to pull in that full object into the query result ( kind of like .fetch() )

Hi folks,

I’ve got a question that is kind of related, though slightly different…

I’m storing some rather nested data that contains pointers, either to media or other documents, etc.

I’ve written some code dynamically build the include paths on the server so that the data all gets automatically included when fetching a given doc/page. This is all working pretty nicely, but when it comes to updating/saving a doc, I need to convert them all back to pointers, but include removes the class reference, which makes this a bit tricky.

If include could keep the class reference in the result, this would make it easier to solve.

Does anyone have a suggestion to solve this?

Maybe you can check the schema.