ueberauth/guardian

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?

@alanraul Closing for now