Filter actions on a controller by permissions
alanraul opened this issue · 6 comments
Hi.
I am trying to filter actions on a controller according to the permissions of the token
plug Guardian.Permissions, [ensure: %{admin: [:all]}] when not action in [:index]
plug Guardian.Permissions, [ensure: %{default: [:read, :update]}] when action in [:show]
but this doesn't work, I'm using guardian - 2.0 and phoenix - 1.5
@alanraul Did you see the docs here https://github.com/ueberauth/guardian/blob/master/lib/guardian/permissions.ex you will need to make this part of your pipeline, do you have a bigger example of your setup?
Hi @Hanspagh. I read this doc https://hexdocs.pm/guardian/Guardian.Permissions.html#module-using-with-plug
I understand that this part validates if your token has all or at least one of the permissions but when validating your token it has access to all the actions of a controller, isn't it?
This is an example of auth pipeline, router and controller
defmodule UserApi.Guardian.AuthPipeline do
use Guardian.Plug.Pipeline, otp_app: :user_api,
module: UserApi.Guardian,
error_handler: UserApi.ErrorAuth
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
plug Guardian.Plug.EnsureAuthenticated
plug Guardian.Plug.LoadResource
end
defmodule UserApiWeb.Router do
use UserApiWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
pipeline :auth do
plug UserApi.Guardian.AuthPipeline
end
scope "/api/v1", UserApiWeb do
pipe_through :api
post "/user/sign_in", UserController, :sign_in
resources "/user", UserController, only: [:create]
end
scope "/api/v1", UserApiWeb do
pipe_through [:api, :auth]
resources "/user", UserController, except: [:new, :edit, :create]
end
end
defmodule UserApiWeb.UserController do
use UserApiWeb, :controller
alias UserApi.Contexts.{User, UserManager}
alias UserApiWeb.UserView
action_fallback UserApiWeb.FallbackController
plug Guardian.Permissions, [ensure: %{admin: [:all]}] when not action in [:index]
plug Guardian.Permissions, [ensure: %{default: [:read, :update]}] when action in [:show]
@doc """
List users
"""
@spec index(map, map):: map
def index(conn, params) do
{:success, UserView, "index.json", users: UserManager.list()}
end
@doc """
Create user
"""
@spec create(map, map):: map
def create(conn, %{"user" => params}) do
with {:ok, user} <- UserManager.create(params) do
{:success, UserView, "user.json", user: user}
end
end
@doc """
sign in user
"""
@spec sign_in(map, map):: map
def sign_in(conn, %{"email" => email, "password" => password}) do
case UserManager.sign_in(email, password) do
{:ok, token, claims} ->
{:success, UserView, "jwt.json", jwt: token, user_id: claims["user_id"]}
{:error, error} ->
{:error, error}
end
end
@doc """
Show user
"""
# @spec show(map, map) :: tuple
def show(_conn, %{"id" => id}) do
with %User{} = user <- UserManager.get(id) do
{:success, UserView, "show.json", user: user}
end
end
end
Sorry for the late resposne, The above should work, which error are you seing excatly?
The problem I have is not an error, but rather that when generating a token, it has access to any endpoint defined in the router, whether it was created with admin or default permissions. What I would like to know is how to do that if I define a token with default permissions can not update or delete something because as the code is defined if you can do it because your token is valid.
I tried to reproduce your problem, but I cant seem to not make it work.
I have created this repo https://github.com/Hanspagh/guardian_permission_test as an example, maybe you can tell me what you have different?