Skip to content

Commit cdaaf0e

Browse files
committed
chore: allow setting context to Ash.can
1 parent 1574c48 commit cdaaf0e

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

lib/ash.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,10 @@ defmodule Ash do
892892
doc:
893893
"A value that implements the `Ash.Scope.ToOpts` protocol. Will overwrite any actor, tenant or context provided. See `Ash.Context` for more."
894894
],
895+
context: [
896+
type: :map,
897+
doc: "Context to set on the query/changeset/action_input being authorized"
898+
],
895899
run_queries?: [
896900
type: :boolean,
897901
doc: "Whether or not to run queries. If set to `true`, `:maybe` will not be returned.",

lib/ash/can.ex

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ defmodule Ash.Can do
7474
opts = Keyword.put_new(opts, :maybe_is, :maybe)
7575
opts = Keyword.put_new(opts, :run_queries?, true)
7676
opts = Keyword.put_new(opts, :filter_with, :filter)
77+
context = opts[:context] || %{}
7778

7879
{actor, opts} =
7980
if is_struct(actor_or_scope) and Ash.Scope.ToOpts.impl_for(actor_or_scope) do
@@ -85,6 +86,8 @@ defmodule Ash.Can do
8586
{actor_or_scope, opts}
8687
end
8788

89+
opts = Keyword.update(opts, :context, context, &Ash.Helpers.deep_merge_maps(&1, context))
90+
8891
{resource, action_or_query_or_changeset, input, opts} =
8992
case resource_subject_input(action_or_query_or_changeset, domain, actor, opts) do
9093
{resource, action_or_query_or_changeset, input, new_opts} ->
@@ -115,34 +118,56 @@ defmodule Ash.Can do
115118
if opts[:data] do
116119
Ash.Changeset.for_update(opts[:data], name, input,
117120
actor: actor,
118-
tenant: opts[:tenant]
121+
tenant: opts[:tenant],
122+
context: opts[:context]
119123
)
120124
else
121125
resource
122126
|> struct()
123-
|> Ash.Changeset.for_update(name, input, actor: actor, tenant: opts[:tenant])
127+
|> Ash.Changeset.for_update(name, input,
128+
actor: actor,
129+
tenant: opts[:tenant],
130+
context: opts[:context]
131+
)
124132
end
125133

126134
%{type: :create, name: name} ->
127-
Ash.Changeset.for_create(resource, name, input, actor: actor, tenant: opts[:tenant])
135+
Ash.Changeset.for_create(resource, name, input,
136+
actor: actor,
137+
tenant: opts[:tenant],
138+
context: opts[:context]
139+
)
128140

129141
%{type: :read, name: name} ->
130-
Ash.Query.for_read(resource, name, input, actor: actor, tenant: opts[:tenant])
142+
Ash.Query.for_read(resource, name, input,
143+
actor: actor,
144+
tenant: opts[:tenant],
145+
context: opts[:context]
146+
)
131147

132148
%{type: :destroy, name: name} ->
133149
if opts[:data] do
134150
Ash.Changeset.for_destroy(opts[:data], name, input,
135151
actor: actor,
136-
tenant: opts[:tenant]
152+
tenant: opts[:tenant],
153+
context: opts[:context]
137154
)
138155
else
139156
resource
140157
|> struct()
141-
|> Ash.Changeset.for_destroy(name, input, actor: actor, tenant: opts[:tenant])
158+
|> Ash.Changeset.for_destroy(name, input,
159+
actor: actor,
160+
tenant: opts[:tenant],
161+
context: opts[:context]
162+
)
142163
end
143164

144165
%{type: :action, name: name} ->
145-
Ash.ActionInput.for_action(resource, name, input, actor: actor, tenant: opts[:tenant])
166+
Ash.ActionInput.for_action(resource, name, input,
167+
actor: actor,
168+
tenant: opts[:tenant],
169+
context: opts[:context]
170+
)
146171

147172
_ ->
148173
raise ArgumentError,
@@ -249,32 +274,56 @@ defmodule Ash.Can do
249274

250275
{%Ash.Query{} = query, name} ->
251276
query
252-
|> Ash.Query.for_read(name, %{})
277+
|> Ash.Query.for_read(name, %{},
278+
actor: actor,
279+
tenant: opts[:tenant],
280+
context: opts[:context]
281+
)
253282
|> resource_subject_input(domain, actor, opts)
254283

255284
{%Ash.Changeset{} = changeset, name} ->
256285
changeset
257-
|> Ash.Changeset.for_action(name, %{})
286+
|> Ash.Changeset.for_action(name, %{},
287+
actor: actor,
288+
tenant: opts[:tenant],
289+
context: opts[:context]
290+
)
258291
|> resource_subject_input(domain, actor, opts)
259292

260293
{%Ash.ActionInput{} = input, name} ->
261294
input
262-
|> Ash.ActionInput.for_action(name, %{})
295+
|> Ash.ActionInput.for_action(name, %{},
296+
actor: actor,
297+
tenant: opts[:tenant],
298+
context: opts[:context]
299+
)
263300
|> resource_subject_input(domain, actor, opts)
264301

265302
{%Ash.Query{} = query, name, input} ->
266303
query
267-
|> Ash.Query.for_read(name, input)
304+
|> Ash.Query.for_read(name, input,
305+
actor: actor,
306+
tenant: opts[:tenant],
307+
context: opts[:context]
308+
)
268309
|> resource_subject_input(domain, actor, opts)
269310

270311
{%Ash.Changeset{} = changeset, name, input} ->
271312
changeset
272-
|> Ash.Changeset.for_action(name, input)
313+
|> Ash.Changeset.for_action(name, input,
314+
actor: actor,
315+
tenant: opts[:tenant],
316+
context: opts[:context]
317+
)
273318
|> resource_subject_input(domain, actor, opts)
274319

275320
{%Ash.ActionInput{} = input, name, action_input} ->
276321
input
277-
|> Ash.ActionInput.for_action(name, action_input)
322+
|> Ash.ActionInput.for_action(name, action_input,
323+
actor: actor,
324+
tenant: opts[:tenant],
325+
context: opts[:context]
326+
)
278327
|> resource_subject_input(domain, actor, opts)
279328

280329
{%resource{} = record, name}
@@ -318,6 +367,7 @@ defmodule Ash.Can do
318367
Ash.Query.for_read(resource, action.name, input,
319368
domain: domain,
320369
tenant: opts[:tenant],
370+
context: opts[:context],
321371
actor: actor
322372
), input, data: [record]}
323373

@@ -326,6 +376,7 @@ defmodule Ash.Can do
326376
Ash.ActionInput.for_action(resource, action.name, input,
327377
domain: domain,
328378
tenant: opts[:tenant],
379+
context: opts[:context],
329380
actor: actor
330381
), input}
331382

@@ -334,6 +385,7 @@ defmodule Ash.Can do
334385
Ash.Changeset.for_create(resource, action.name, input,
335386
domain: domain,
336387
tenant: opts[:tenant],
388+
context: opts[:context],
337389
actor: actor
338390
), input}
339391

@@ -346,6 +398,7 @@ defmodule Ash.Can do
346398
Ash.Changeset.for_action(record, action.name, input,
347399
domain: domain,
348400
tenant: opts[:tenant],
401+
context: opts[:context],
349402
actor: actor
350403
), input}
351404

@@ -354,6 +407,7 @@ defmodule Ash.Can do
354407
Ash.Query.for_read(resource, action.name, input,
355408
domain: domain,
356409
tenant: opts[:tenant],
410+
context: opts[:context],
357411
actor: actor
358412
), input}
359413

@@ -362,6 +416,7 @@ defmodule Ash.Can do
362416
Ash.ActionInput.for_action(resource, action.name, input,
363417
domain: domain,
364418
tenant: opts[:tenant],
419+
context: opts[:context],
365420
actor: actor
366421
), input}
367422

@@ -370,6 +425,7 @@ defmodule Ash.Can do
370425
Ash.Changeset.for_create(resource, action.name, input,
371426
domain: domain,
372427
tenant: opts[:tenant],
428+
context: opts[:context],
373429
actor: actor
374430
), input}
375431

0 commit comments

Comments
 (0)