Closed pedromvieira closed 6 years ago
With a simpler permission model, same thing occurs, manually works but plug dont. Do we need to write our plug?
TOKEN_MODULE
use Guardian, otp_app: :phishx,
secret_key: @key,
permissions: %{
default: [:account, :group, :mgmt],
account: [:read, :export, :write, :delete, :dashboard],
group: [:read, :export, :write, :delete, :dashboard],
mgmt: [:read, :export, :write, :delete, :dashboard],
}
CLAIM
%{"aud" => "phishx", "exp" => 1517416805,
"extra" => %{"id" => 1, "subdomain" => "aaa", "type" => "user"},
"iat" => 1514997605, "iss" => "phishx",
"jti" => "729af38d-8251-4523-af24-8e5611b990f6", "nbf" => 1514997604,
"perms" => %{"mgmt" => 31}, "sub" => "user|aaa|1", "typ" => "user"}
DECODE
all = Phishx.Guardian.decode_permissions(claims)
%{mgmt: [:dashboard, :delete, :export, :read, :write]}
test = %{mgmt: [:write]}
%{mgmt: [:write]}
Phishx.Guardian.any_permissions?(all, test)
true
Just to make it clear, with this simple custom plug works. Is there a way to do it with vanilla guardian?
PLUG EXAMPLE
defmodule Phishx.Guardian.Plug.Auth do
@moduledoc """
Guardian Auth Plug.
"""
import Plug.Conn
alias Phishx.Guardian
alias Phishx.Guardian.ErrorHandler
def init(options), do: options
def call(conn, {cmd, test} = options) do
permissions =
conn.private.guardian_default_claims["perms"]
|> Guardian.decode_permissions()
result =
case cmd do
:one_of ->
Guardian.any_permissions?(permissions, test)
:ensure ->
Guardian.all_permissions?(permissions, test)
end
auth(conn, result)
end
defp auth(conn, true = result), do: conn
defp auth(conn, _), do: ErrorHandler.auth_error(conn, {:unauthorized, __MODULE__}, [])
end
CONTROLLER CALL
plug Phishx.Guardian.Plug.Auth,
{:one_of, %{ account: [:super], group: [:super], mgmt: [:read]} }
when action in ~w(index)a
def index(conn, _params) do
render(conn, "index.html")
end
@pedromvieira this sounds like you may have discovered a bug (or a needed feature). Have you had a chance to peek at the Guardian plug? I'll try to set aside some time this week to look into this more for you.
@doomspork Yes. No luck with Guardian.Plug.
@pedromvieira where does the "perms"
key in your claims come from? It should be "pem"
. How are you creating your token?
From the docs, you should use the build_claims
callback in your implementation module
def build_claims(claims, _resource, opts) do
claims =
claims
|> encode_permissions_into_claims!(Keyword.get(opts, :permissions))
{:ok, claims}
end
Where the :permissions
key for the options is chosen by you. To use it you'd do something like:
Phishx.Guardian.encode_and_sign(user, %{}, permissions: %{default: [:mgmt], user_actions: [:dashboard]})
The same is true for sign_in
I'm trying to use Bitwise plug without success. My token works and I can use any_permissions? and all_permissions? manually. Any_permissions could check both conditions on a map? Our user has a "profile" and "permissions", like "account_user" = account (default) + read (user_actions).
TOKEN_MODEL
CLAIM EXAMPLE
PERMISSIONS DECODE
MANUAL VALIDATION
ONE_OF PLUG
This plugs always halts.