Skip to content

Commit ecbf40c

Browse files
committed
Add a handle_authorize hook which is executed on all actions (before anything).
This way I can simply add authorization on the record that's properly loaded and scoped by ja_resource for all routes at once. Show, delete and update will call the method with the actual model to be operated on (but before anything is done to the model!). index and create actions will pass in the model() module instead (since we're operating on a collection/adding a record not yet in the db). This was intended for integration with bodyguard. I had to do the following: def records(conn) do scope(conn, model()) end # this solves the auth for show, update and delete (but not index or create) def record(conn, id) do r = super(conn, id) authorize!(conn, r, policy: Midori.Bot.Policy) r end def handle_index(conn, attributes) do authorize!(conn, Bot) super(conn, attributes) end def handle_create(conn, attributes) do authorize!(conn, Bot) super(conn, attributes) end I wanted a solution that would take care of index and create as well, because having to do it manually action by action is error-prone.
1 parent 8be4c16 commit ecbf40c

7 files changed

Lines changed: 39 additions & 3 deletions

File tree

lib/ja_resource/authorize.ex

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule JaResource.Authorize do
2+
use Behaviour
3+
4+
@moduledoc """
5+
Provides the `handle_authorize/0` callback used to authorize the resource.
6+
7+
This behaviour is used by all JaResource actions.
8+
"""
9+
10+
@doc """
11+
Called before all the actions with the model. Useful for authorizing.
12+
"""
13+
@callback handle_authorize(Plug.Conn.t, JaResource.record) :: any
14+
15+
defmacro __using__(_) do
16+
quote do
17+
@behaviour JaResource.Authorize
18+
19+
def handle_authorize(model, _conn), do: model
20+
21+
defoverridable [handle_authorize: 2]
22+
end
23+
end
24+
end

lib/ja_resource/create.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ defmodule JaResource.Create do
6565
def call(controller, conn) do
6666
merged = JaResource.Attributes.from_params(conn.params)
6767
attributes = controller.permitted_attributes(conn, merged, :create)
68+
69+
controller.handle_authorize(controller.model(), conn)
70+
6871
conn
6972
|> controller.handle_create(attributes)
7073
|> JaResource.Create.insert(controller)

lib/ja_resource/delete.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ defmodule JaResource.Delete do
5959
def call(controller, conn) do
6060
model = controller.record(conn, conn.params["id"])
6161

62+
controller.handle_authorize(model, conn)
63+
6264
conn
6365
|> controller.handle_delete(model)
6466
|> JaResource.Delete.respond(conn)

lib/ja_resource/index.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ defmodule JaResource.Index do
119119
Execute the index action on a given module implementing Index behaviour and conn.
120120
"""
121121
def call(controller, conn) do
122+
controller.handle_authorize(controller.model(), conn)
123+
122124
conn
123125
|> controller.handle_index(conn.params)
124126
|> JaResource.Index.filter(conn, controller)

lib/ja_resource/model.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defmodule JaResource.Model do
2525
defmacro __using__(_) do
2626
quote do
2727
@behaviour JaResource.Model
28+
use JaResource.Authorize
2829

2930
@inferred_model JaResource.Model.model_from_controller(__MODULE__)
3031
def model(), do: @inferred_model

lib/ja_resource/show.ex

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ defmodule JaResource.Show do
5757
Execute the show action on a given module implementing Show behaviour and conn.
5858
"""
5959
def call(controller, conn) do
60-
conn
61-
|> controller.handle_show(conn.params["id"])
62-
|> JaResource.Show.respond(conn, controller)
60+
model = controller.handle_show(conn.params["id"])
61+
62+
controller.handle_authorize(model, conn)
63+
64+
JaResource.Show.respond(model, conn, controller)
6365
end
6466

6567
@doc false

lib/ja_resource/update.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ defmodule JaResource.Update do
7272
merged = JaResource.Attributes.from_params(conn.params)
7373
attributes = controller.permitted_attributes(conn, merged, :update)
7474

75+
controller.handle_authorize(model, conn)
76+
7577
conn
7678
|> controller.handle_update(model, attributes)
7779
|> JaResource.Update.update(controller)

0 commit comments

Comments
 (0)