Please add example for using plugs with fallback controllers
ndarilek opened this issue · comments
Hey, thanks for this library. Currently using it to add authorization to my app, and the documentation has been mostly very clear.
I'm starting to replace my initial simplistic authorization flow with Bodyguard, and am having some issues using the Authorize plug with a fallback controller. First, I have a policy definition like so:
defmodule ScribeWeb.Policy do
@behaviour Bodyguard.Policy
alias __MODULE__
alias Scribe.Auth.User
def authorize(_, %User{role: :admin}, _), do: true
def authorize(:new_document, %User{role: :customer}, _), do: true
def authorize(:new_document, %User{role: :demo}, _), do: true
def authorize(_, _, _), do: false
end
Next I have this as an administrative-only controller:
defmodule ScribeWeb.AdminUserController do
use ScribeWeb, :controller
alias Scribe.Auth
alias Scribe.Auth.User
action_fallback ScribeWeb.FallbackController
plug Bodyguard.Plug.Authorize
...
end
And this as my fallback. Note that this throws a warning about function calls that won't match, because I'm trying to debug it:
defmodule ScribeWeb.FallbackController do
use ScribeWeb, :controller
def call(conn, params) do
IO.inspect(params)
conn
end
def call(conn, {:error, :unauthorized}) do
conn
|> put_status(:not_found)
|> put_view(ScribeWeb.ErrorView)
|> render(:not_found)
end
end
Unfortunately this doesn't work, My FallbackController
is never hit. I'm unclear as to whether my use of the Authorize plug is incompatible with Phoenix fallbacks, if I have to perform checks on each individual action I want to protect, etc. Ideally I'd like to replace my entire authorization flow with a central policy definition, and some smarter return codes like :requires_login if a user isn't authenticated, :requires_demo if a user needs to request a demo to access the specified URL, etc.
Thanks for any help.
You can find a nice example here https://hexdocs.pm/bodyguard/Bodyguard.Plug.Authorize.html
Believe the key bit you need for you case is adding this fallback: ScribeWeb.FallbackController
to your plug Bodyguard.Plug.Authorize
call
Added example and clarification to the README – thanks!