defmodule PotionIngredients.Utils.Token do use Joken.Config def decode(token, secret) do signer = Joken.Signer.create("HS256", secret) token |> clean_token() |> verify_and_validate(signer) end defp clean_token(token), do: token |> String.replace("Bearer ", "") # 1 hour def token_config, do: default_claims(default_exp: 60 * 60) def check_scope(headers, roles) do user_roles = get_app_user(headers) |> get_user_roles() all = check_all_roles(user_roles, get_all_scopes(roles)) any = check_any_role(user_roles, get_any_scopes(roles)) case [all, any] do [true, false] -> true [false, false] -> false [true, true] -> true [false, true] -> true _ -> false end end def get_app_user(headers) do Enum.find(headers, fn {key, _header} -> key == "app_token" end) |> case do nil -> nil {_, user} -> Poison.decode!(user) end end defp get_user_roles(user) do Map.get(user, "roles", %{}) end defp get_all_scopes(nil), do: nil defp get_all_scopes(opts) do try do [all: all] = opts all rescue _ -> [] end end defp get_any_scopes(nil), do: nil defp get_any_scopes(opts) do try do [any: any] = opts any rescue _ -> [] end end defp check_all_roles(_user_roles, []), do: false defp check_all_roles(user_roles, all) do if(user_roles != []) do mapped = Map.keys(user_roles) Enum.all?(all, fn role -> Enum.find(mapped, fn scope -> scope == role end) end) else false end end defp check_any_role(user_roles, any) do if(user_roles != []) do mapped = Map.keys(user_roles) Enum.any?(any, fn role -> Enum.find(mapped, fn scope -> scope == role end) end) else false end end end