Skip to content

Commit 4618a1c

Browse files
authored
fix: issues with multitenancy bypass in related queries (#205)
1 parent 00117a7 commit 4618a1c

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

lib/join.ex

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,7 @@ defmodule AshSql.Join do
407407
filter_subquery? = Keyword.get(opts, :filter_subquery?, false)
408408
parent_resources = Keyword.get(opts, :parent_stack, [relationship.source])
409409

410-
read_action =
411-
relationship.read_action ||
412-
Ash.Resource.Info.primary_action!(relationship.destination, :read).name
410+
read_action = get_read_action(relationship)
413411

414412
context = Map.delete(query.__ash_bindings__.context, :data_layer)
415413

@@ -436,17 +434,17 @@ defmodule AshSql.Join do
436434
end)
437435
|> Ash.Query.do_filter(opts[:apply_filter], parent_stack: parent_resources)
438436
|> then(fn query ->
439-
if query.__validated_for_action__ == read_action do
437+
if query.__validated_for_action__ == read_action.name do
440438
query
441439
else
442-
Ash.Query.for_read(query, read_action, %{},
440+
Ash.Query.for_read(query, read_action.name, %{},
443441
actor: context[:private][:actor],
444442
tenant: context[:private][:tenant]
445443
)
446444
end
447445
end)
448446
|> Ash.Query.unset([:distinct, :select, :limit, :offset])
449-
|> handle_attribute_multitenancy(tenant)
447+
|> handle_attribute_multitenancy(tenant, read_action)
450448
|> hydrate_refs(context[:private][:actor])
451449
|> then(fn query ->
452450
if sort? do
@@ -507,8 +505,9 @@ defmodule AshSql.Join do
507505
end
508506

509507
@doc false
510-
def handle_attribute_multitenancy(query, tenant) do
511-
if tenant && Ash.Resource.Info.multitenancy_strategy(query.resource) == :attribute do
508+
def handle_attribute_multitenancy(query, tenant, read_action \\ nil) do
509+
if tenant && Ash.Resource.Info.multitenancy_strategy(query.resource) == :attribute &&
510+
(is_nil(read_action) || read_action.multitenancy not in [:bypass, :bypass_all]) do
512511
multitenancy_attribute = Ash.Resource.Info.multitenancy_attribute(query.resource)
513512

514513
if multitenancy_attribute do
@@ -1367,4 +1366,12 @@ defmodule AshSql.Join do
13671366
{dynamic, acc} = AshSql.Expr.dynamic_expr(root_query, filter, bindings, true)
13681367
{from(row in query, where: ^dynamic), acc}
13691368
end
1369+
1370+
defp get_read_action(%{read_action: nil} = rel) do
1371+
Ash.Resource.Info.primary_action!(rel.destination, :read)
1372+
end
1373+
1374+
defp get_read_action(rel) do
1375+
Ash.Resource.Info.action(rel.destination, rel.read_action)
1376+
end
13701377
end

lib/query.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ defmodule AshSql.Query do
644644
[first_rel_name | _] ->
645645
relationship = Ash.Resource.Info.relationship(resource, first_rel_name)
646646

647+
if is_nil(relationship) do
648+
raise "No such relationship #{inspect(resource)}.#{relationship}. aggregates: #{inspect(aggregates)}"
649+
end
650+
647651
rel_fields =
648652
if relationship && !Map.get(relationship, :no_attributes?) &&
649653
Map.get(relationship, :source_attribute) do
@@ -652,7 +656,7 @@ defmodule AshSql.Query do
652656
[]
653657
end
654658

655-
if relationship && relationship.filter do
659+
if relationship.filter do
656660
extract_parent_attrs_from_filter(relationship.filter, query)
657661
else
658662
[]

0 commit comments

Comments
 (0)