Is this possible to encode as a policy?

bypass action(:my_action) do
authorize_if expr(
^context(:organization_id) == ^tenant() and
^context(:some_key) == ^arg(:some_other_key)
)
end
bypass action(:my_action) do
authorize_if expr(
^context(:organization_id) == ^tenant() and
^context(:some_key) == ^arg(:some_other_key)
)
end
basically, I want to check if one of the input values is equal to some other value I'm passing as context to the action. the policy evaluates to true and everything works when those values mach. But I'm getting a weird error when they don't match.
** (BadMapError) expected a map, got: [tenant: ..., args: %{some_other_key: "a", context: %{private: %{some_key: "b"}}}
** (BadMapError) expected a map, got: [tenant: ..., args: %{some_other_key: "a", context: %{private: %{some_key: "b"}}}
Is this possible to accomplish?
8 Replies
sevenseacat
sevenseacat4mo ago
you've missed wrapping it in an expr()
ggarciajr
ggarciajrOP4mo ago
@sevenseacat that was a copy+paste mistake. I just edit the original message
ZachDaniel
ZachDaniel4mo ago
Hmm...that might be a bug? Or somehow you're setting the context somewhere to a keyword list instead of a map? Can you reproduce somewhere I can run?
ggarciajr
ggarciajrOP4mo ago
This is how I'm setting up things in the controller:
opts = [
tenant: Ash.PlugHelpers.get_tenant(conn),
context: %{
event: conn.private.webhook.event,
organization_id: conn.private.webhook.organization_id
}
]

MyDomain.create_event_from_webhook(event, payload, opts)
opts = [
tenant: Ash.PlugHelpers.get_tenant(conn),
context: %{
event: conn.private.webhook.event,
organization_id: conn.private.webhook.organization_id
}
]

MyDomain.create_event_from_webhook(event, payload, opts)
event and payload are coming from the request. here is the code from the domain
resource MyDomain.Event do
define :create_event_from_webhook,
action: :create_from_webhook,
args: [:event, :payload]
end
resource MyDomain.Event do
define :create_event_from_webhook,
action: :create_from_webhook,
args: [:event, :payload]
end
here is the action definition
actions do
action :create_from_webhook do
argument :event, :string, allow_nil?: false
argument :payload, :map, allow_nil?: false

run fn input, opts ->
dbg(input)
dbg(opts)

:ok
end
end
end
actions do
action :create_from_webhook do
argument :event, :string, allow_nil?: false
argument :payload, :map, allow_nil?: false

run fn input, opts ->
dbg(input)
dbg(opts)

:ok
end
end
end
and finally the policies
policies do
bypass action(:create_from_webhook) do
authorize_if expr(
^context(:organization_id) == ^tenant() and
^context(:event) == ^arg(:event)
)
end

policy always() do
forbid_if always()
end
end
policies do
bypass action(:create_from_webhook) do
authorize_if expr(
^context(:organization_id) == ^tenant() and
^context(:event) == ^arg(:event)
)
end

policy always() do
forbid_if always()
end
end
ZachDaniel
ZachDaniel4mo ago
What is the stack trace for the error?
ggarciajr
ggarciajrOP4mo ago
(ash 3.5.15) lib/ash/expr/expr.ex:229: anonymous fn/2 in Ash.Expr.fill_template/2
(ash 3.5.15) lib/ash/expr/expr.ex:522: Ash.Expr.walk_template/2
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/expr/expr.ex:499: Ash.Expr.walk_template/2
(ash 3.5.15) lib/ash/expr/expr.ex:425: Ash.Expr.walk_template/2
(ash 3.5.15) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.expand_description/3
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:512: Ash.Error.Forbidden.Policy.describe/5
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:484: Ash.Error.Forbidden.Policy.describe_check/8
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:448: anonymous fn/7 in Ash.Error.Forbidden.Policy.describe_checks/6
(elixir 1.18.4) lib/enum.ex:2546: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:412: Ash.Error.Forbidden.Policy.describe_checks/6
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:327: Ash.Error.Forbidden.Policy.explain_policy/6
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:244: anonymous fn/4 in Ash.Error.Forbidden.Policy.get_breakdown/4
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:242: Ash.Error.Forbidden.Policy.get_breakdown/4
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:96: Ash.Error.Forbidden.Policy.report/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:44: Ash.Error.Forbidden.Policy.exception/1
(ash 3.5.15) lib/ash/expr/expr.ex:229: anonymous fn/2 in Ash.Expr.fill_template/2
(ash 3.5.15) lib/ash/expr/expr.ex:522: Ash.Expr.walk_template/2
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/expr/expr.ex:499: Ash.Expr.walk_template/2
(ash 3.5.15) lib/ash/expr/expr.ex:425: Ash.Expr.walk_template/2
(ash 3.5.15) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.expand_description/3
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:512: Ash.Error.Forbidden.Policy.describe/5
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:484: Ash.Error.Forbidden.Policy.describe_check/8
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:448: anonymous fn/7 in Ash.Error.Forbidden.Policy.describe_checks/6
(elixir 1.18.4) lib/enum.ex:2546: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:412: Ash.Error.Forbidden.Policy.describe_checks/6
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:327: Ash.Error.Forbidden.Policy.explain_policy/6
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:244: anonymous fn/4 in Ash.Error.Forbidden.Policy.get_breakdown/4
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:242: Ash.Error.Forbidden.Policy.get_breakdown/4
(elixir 1.18.4) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:96: Ash.Error.Forbidden.Policy.report/2
(ash 3.5.15) lib/ash/error/forbidden/policy.ex:44: Ash.Error.Forbidden.Policy.exception/1
I forgot the first line:
(stdlib 6.2.2) :maps.find(:event, [tenant: "tenant_id", args: %{payload: %{***}, event: "customerUpdated"}, context: %{private: %{actor: %{***}, authorize?: true}, event: "acustomerUpdated", organization_id: "tenant_id"}, changeset: nil])
(stdlib 6.2.2) :maps.find(:event, [tenant: "tenant_id", args: %{payload: %{***}, event: "customerUpdated"}, context: %{private: %{actor: %{***}, authorize?: true}, event: "acustomerUpdated", organization_id: "tenant_id"}, changeset: nil])
ZachDaniel
ZachDaniel4mo ago
This does look like a bug If you could open an issue, and ideally create a small reproduction project or test case that reproduces the issue, I will look into it
ggarciajr
ggarciajrOP4mo ago
will do it later today. thank you

Did you find this page helpful?