From f86fd5625d55fcd838e08d625c31e6777087da33 Mon Sep 17 00:00:00 2001 From: Jeroen Visser Date: Thu, 16 Jul 2020 00:40:54 +0200 Subject: [PATCH] Add optional default_authorize callback This allows setting the `authorize: ...` value for all fields if none was set. This allows for an easier adoption for APIs that might previously not have any role-based authorization. Defaulting to their default role, for instance, :admin, and only adding `authorize: ...` where authorization can be relaxed. --- lib/authorization.ex | 5 ++++- lib/middlewares/object_authorization.ex | 7 +++++++ lib/rajska.ex | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/authorization.ex b/lib/authorization.ex index dc9accb..e02a8fe 100644 --- a/lib/authorization.ex +++ b/lib/authorization.ex @@ -30,6 +30,8 @@ defmodule Rajska.Authorization do @callback context_user_authorized?(context, scoped_struct, rule) :: boolean() + @callback default_authorize(context, scoped_struct) :: role() | nil + @optional_callbacks get_current_user: 1, get_ip: 1, get_user_role: 1, @@ -38,5 +40,6 @@ defmodule Rajska.Authorization do has_user_access?: 3, unauthorized_message: 1, context_role_authorized?: 2, - context_user_authorized?: 3 + context_user_authorized?: 3, + default_authorize: 2 end diff --git a/lib/middlewares/object_authorization.ex b/lib/middlewares/object_authorization.ex index 6c13476..29d7e7c 100644 --- a/lib/middlewares/object_authorization.ex +++ b/lib/middlewares/object_authorization.ex @@ -88,10 +88,17 @@ defmodule Rajska.ObjectAuthorization do defp authorize_object(object, fields, resolution) do object |> Type.meta(:authorize) + |> default_authorize(resolution.context, object) |> authorized?(resolution.context, object) |> put_result(fields, resolution, object) end + defp default_authorize(nil, context, object) do + Rajska.apply_auth_mod(context, :default_authorize, [context, object]) + end + + defp default_authorize(authorize, _context, _object), do: authorize + defp authorized?(nil, _, object), do: raise "No meta authorize defined for object #{inspect object.identifier}" defp authorized?(permission, context, _object) do diff --git a/lib/rajska.ex b/lib/rajska.ex index 28c2497..173cac1 100644 --- a/lib/rajska.ex +++ b/lib/rajska.ex @@ -65,7 +65,8 @@ defmodule Rajska do defmacro __using__(opts \\ []) do super_role = Keyword.get(opts, :super_role, :admin) valid_roles = Keyword.get(opts, :valid_roles, [super_role]) - default_rule = Keyword.get(opts, :default_rule, :default) + default_rule = Keyword.get(opts, :default_rule, :default) + default_authorize = Keyword.get(opts, :default_authorize, nil) quote do @behaviour Authorization @@ -130,6 +131,8 @@ defmodule Rajska do |> get_current_user() |> has_user_access?(scoped_struct, rule) end + + def default_authorize(_context, _object), do: unquote(default_authorize) defoverridable Authorization end