Ignoring multitenancy in joined resources

I have a test that started failing since I updated Ash.

The test checks whether we have properly configured policy for the organisation resource. Here’s the code, although it’s not that relevant to the issue: omedis/test/omedis/accounts/accounts_test.exs at 15bf4758ff01ee4c9386eeb6bb9393a58f3554a9 · 3Stones-io/omedis · GitHub

The main issue lies in the fact that in the policy check (omedis/lib/omedis/accounts/organisation/checks/can_update_organisation.ex at 15bf4758ff01ee4c9386eeb6bb9393a58f3554a9 · 3Stones-io/omedis · GitHub) we look for associated group membership that can belong to a different tenant than the access right record, and that scenario is covered in the test I referenced earlier.

def match?(actor, %{subject: %{data: organisation, action: %{type: action}}}, _opts) do
  AccessRight
  |> filter(
    resource_name == "Organisation" and exists(group.group_memberships, user_id == ^actor.id)
  )
  |> filter_by_action(action)
  |> Ash.exists?(tenant: organisation)
end

After some time going through all the updates, I pinpointed to the version of ash_sql that introduced the issue (0.2.41) with the following change:

  • apply attribute multitenancy on joined resources

Is there a way I can ignore multitenancy just for this query?

:thinking: this is a difficult one. It was a bug that tenant filters weren’t being applied inside of exists, and the general idea is that a tenant, once applied to a query, is guaranteed to apply to all of its subqueries etc (unless they are not multi tenant).

Something that you could do is set global? true on the access right resource to allow accessing it without a tenant, and then do something like this:

 AccessRight
  |> filter(
    resource_name == "Organisation" and exists(group.group_memberships, user_id == ^actor.id)
  )
  |> filter_by_action(action)
  |> Ash.Query.filter(organisation_id == ^organisation.id)
  |> Ash.exists?()

Then you would not be applying a tenant to the query.

You can then have a policy check that only allows not specifying a tenant in specific circumstances.

That worked, thanks!